• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) Texas Instruments - http://www.ti.com/
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /**
18 * @file OMXCameraAdapter.cpp
19 *
20 * This file maps the Camera Hardware Interface to OMX.
21 *
22 */
23 
24 #include "CameraHal.h"
25 #include "OMXCameraAdapter.h"
26 #include "ErrorUtils.h"
27 #include "TICameraParameters.h"
28 #include <signal.h>
29 #include <math.h>
30 
31 #include <cutils/properties.h>
32 #define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
33 static int mDebugFps = 0;
34 static int mDebugFcs = 0;
35 
36 
37 #define HERE(Msg) {CAMHAL_LOGEB("--===line %d, %s===--\n", __LINE__, Msg);}
38 
39 namespace android {
40 
41 #undef LOG_TAG
42 ///Maintain a separate tag for OMXCameraAdapter logs to isolate issues OMX specific
43 #define LOG_TAG "CameraHAL"
44 
45 //frames skipped before recalculating the framerate
46 #define FPS_PERIOD 30
47 
48 Mutex gAdapterLock;
49 /*--------------------Camera Adapter Class STARTS here-----------------------------*/
50 
initialize(CameraProperties::Properties * caps)51 status_t OMXCameraAdapter::initialize(CameraProperties::Properties* caps)
52 {
53     LOG_FUNCTION_NAME;
54 
55     char value[PROPERTY_VALUE_MAX];
56     property_get("debug.camera.showfps", value, "0");
57     mDebugFps = atoi(value);
58     property_get("debug.camera.framecounts", value, "0");
59     mDebugFcs = atoi(value);
60 
61     TIMM_OSAL_ERRORTYPE osalError = OMX_ErrorNone;
62     OMX_ERRORTYPE eError = OMX_ErrorNone;
63     status_t ret = NO_ERROR;
64 
65 
66     mLocalVersionParam.s.nVersionMajor = 0x1;
67     mLocalVersionParam.s.nVersionMinor = 0x1;
68     mLocalVersionParam.s.nRevision = 0x0 ;
69     mLocalVersionParam.s.nStep =  0x0;
70 
71     mPending3Asettings = 0;//E3AsettingsAll;
72     mPendingCaptureSettings = 0;
73 
74     if ( 0 != mInitSem.Count() )
75         {
76         CAMHAL_LOGEB("Error mInitSem semaphore count %d", mInitSem.Count());
77         LOG_FUNCTION_NAME_EXIT;
78         return NO_INIT;
79         }
80 
81     if (mComponentState != OMX_StateLoaded && mComponentState != OMX_StateInvalid) {
82        CAMHAL_LOGEB("Error mComponentState %d is invalid!", mComponentState);
83        LOG_FUNCTION_NAME_EXIT;
84        return NO_INIT;
85     }
86 
87     ///Update the preview and image capture port indexes
88     mCameraAdapterParameters.mPrevPortIndex = OMX_CAMERA_PORT_VIDEO_OUT_PREVIEW;
89     // temp changed in order to build OMX_CAMERA_PORT_VIDEO_OUT_IMAGE;
90     mCameraAdapterParameters.mImagePortIndex = OMX_CAMERA_PORT_IMAGE_OUT_IMAGE;
91     mCameraAdapterParameters.mMeasurementPortIndex = OMX_CAMERA_PORT_VIDEO_OUT_MEASUREMENT;
92     //currently not supported use preview port instead
93     mCameraAdapterParameters.mVideoPortIndex = OMX_CAMERA_PORT_VIDEO_OUT_PREVIEW;
94 
95     eError = OMX_Init();
96     if (eError != OMX_ErrorNone) {
97       CAMHAL_LOGEB("Error OMX_Init -0x%x", eError);
98       return eError;
99     }
100 
101     ///Get the handle to the OMX Component
102     eError = OMXCameraAdapter::OMXCameraGetHandle(&mCameraAdapterParameters.mHandleComp, (OMX_PTR)this);
103     if(eError != OMX_ErrorNone) {
104         CAMHAL_LOGEB("OMX_GetHandle -0x%x", eError);
105     }
106     GOTO_EXIT_IF((eError != OMX_ErrorNone), eError);
107 
108     CAMHAL_LOGVB("OMX_GetHandle -0x%x sensor_index = %lu", eError, mSensorIndex);
109     eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
110                                   OMX_CommandPortDisable,
111                                   OMX_ALL,
112                                   NULL);
113 
114     if(eError != OMX_ErrorNone) {
115          CAMHAL_LOGEB("OMX_SendCommand(OMX_CommandPortDisable) -0x%x", eError);
116     }
117     GOTO_EXIT_IF((eError != OMX_ErrorNone), eError);
118 
119     // Register for port enable event
120     ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
121                                  OMX_EventCmdComplete,
122                                  OMX_CommandPortEnable,
123                                  mCameraAdapterParameters.mPrevPortIndex,
124                                  mInitSem);
125     if(ret != NO_ERROR) {
126          CAMHAL_LOGEB("Error in registering for event %d", ret);
127          goto EXIT;
128     }
129 
130     // Enable PREVIEW Port
131     eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
132                                  OMX_CommandPortEnable,
133                                  mCameraAdapterParameters.mPrevPortIndex,
134                                  NULL);
135     if(eError != OMX_ErrorNone) {
136         CAMHAL_LOGEB("OMX_SendCommand(OMX_CommandPortEnable) -0x%x", eError);
137     }
138     GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
139 
140     // Wait for the port enable event to occur
141     ret = mInitSem.WaitTimeout(OMX_CMD_TIMEOUT);
142     if ( NO_ERROR == ret ) {
143          CAMHAL_LOGDA("-Port enable event arrived");
144     } else {
145          ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
146                             OMX_EventCmdComplete,
147                             OMX_CommandPortEnable,
148                             mCameraAdapterParameters.mPrevPortIndex,
149                             NULL);
150          CAMHAL_LOGEA("Timeout for enabling preview port expired!");
151          goto EXIT;
152      }
153 
154     // Select the sensor
155     OMX_CONFIG_SENSORSELECTTYPE sensorSelect;
156     OMX_INIT_STRUCT_PTR (&sensorSelect, OMX_CONFIG_SENSORSELECTTYPE);
157     sensorSelect.eSensor = (OMX_SENSORSELECT) mSensorIndex;
158     eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, ( OMX_INDEXTYPE ) OMX_TI_IndexConfigSensorSelect, &sensorSelect);
159     if ( OMX_ErrorNone != eError ) {
160         CAMHAL_LOGEB("Error while selecting the sensor index as %d - 0x%x", mSensorIndex, eError);
161         return BAD_VALUE;
162     } else {
163         CAMHAL_LOGDB("Sensor %d selected successfully", mSensorIndex);
164     }
165 
166     printComponentVersion(mCameraAdapterParameters.mHandleComp);
167 
168     mBracketingEnabled = false;
169     mBracketingBuffersQueuedCount = 0;
170     mBracketingRange = 1;
171     mLastBracetingBufferIdx = 0;
172     mOMXStateSwitch = false;
173 
174     mCaptureSignalled = false;
175     mCaptureConfigured = false;
176     mRecording = false;
177     mWaitingForSnapshot = false;
178     mSnapshotCount = 0;
179     mComponentState = OMX_StateLoaded;
180 
181     mCapMode = HIGH_QUALITY;
182     mIPP = IPP_NULL;
183     mVstabEnabled = false;
184     mVnfEnabled = false;
185     mBurstFrames = 1;
186     mCapturedFrames = 0;
187     mPictureQuality = 100;
188     mCurrentZoomIdx = 0;
189     mTargetZoomIdx = 0;
190     mPreviousZoomIndx = 0;
191     mReturnZoomStatus = false;
192     mZoomInc = 1;
193     mZoomParameterIdx = 0;
194     mExposureBracketingValidEntries = 0;
195     mSensorOverclock = false;
196 
197     mDeviceOrientation = 0;
198     mCapabilities = caps;
199     mZoomUpdating = false;
200     mZoomUpdate = false;
201 
202     mEXIFData.mGPSData.mAltitudeValid = false;
203     mEXIFData.mGPSData.mDatestampValid = false;
204     mEXIFData.mGPSData.mLatValid = false;
205     mEXIFData.mGPSData.mLongValid = false;
206     mEXIFData.mGPSData.mMapDatumValid = false;
207     mEXIFData.mGPSData.mProcMethodValid = false;
208     mEXIFData.mGPSData.mVersionIdValid = false;
209     mEXIFData.mGPSData.mTimeStampValid = false;
210     mEXIFData.mModelValid = false;
211     mEXIFData.mMakeValid = false;
212 
213     // initialize command handling thread
214     if(mCommandHandler.get() == NULL)
215         mCommandHandler = new CommandHandler(this);
216 
217     if ( NULL == mCommandHandler.get() )
218     {
219         CAMHAL_LOGEA("Couldn't create command handler");
220         return NO_MEMORY;
221     }
222 
223     ret = mCommandHandler->run("CallbackThread", PRIORITY_URGENT_DISPLAY);
224     if ( ret != NO_ERROR )
225     {
226         if( ret == INVALID_OPERATION){
227             CAMHAL_LOGDA("command handler thread already runnning!!");
228 	    ret = NO_ERROR;
229         } else
230         {
231             CAMHAL_LOGEA("Couldn't run command handlerthread");
232             return ret;
233         }
234     }
235 
236     // initialize omx callback handling thread
237     if(mOMXCallbackHandler.get() == NULL)
238         mOMXCallbackHandler = new OMXCallbackHandler(this);
239 
240     if ( NULL == mOMXCallbackHandler.get() )
241     {
242         CAMHAL_LOGEA("Couldn't create omx callback handler");
243         return NO_MEMORY;
244     }
245 
246     ret = mOMXCallbackHandler->run("OMXCallbackThread", PRIORITY_URGENT_DISPLAY);
247     if ( ret != NO_ERROR )
248     {
249         if( ret == INVALID_OPERATION){
250             CAMHAL_LOGDA("omx callback handler thread already runnning!!");
251 	    ret = NO_ERROR;
252         }else
253         {
254             CAMHAL_LOGEA("Couldn't run omx callback handler thread");
255             return ret;
256         }
257     }
258 
259     //Remove any unhandled events
260     if (!mEventSignalQ.isEmpty()) {
261         for (unsigned int i = 0 ;i < mEventSignalQ.size(); i++ ) {
262             TIUTILS::Message *msg = mEventSignalQ.itemAt(i);
263             //remove from queue and free msg
264             mEventSignalQ.removeAt(i);
265             if ( NULL != msg ) {
266                 free(msg);
267             }
268         }
269     }
270 
271     OMX_INIT_STRUCT_PTR (&mRegionPriority, OMX_TI_CONFIG_3A_REGION_PRIORITY);
272     OMX_INIT_STRUCT_PTR (&mFacePriority, OMX_TI_CONFIG_3A_FACE_PRIORITY);
273     mRegionPriority.nPortIndex = OMX_ALL;
274     mFacePriority.nPortIndex = OMX_ALL;
275 
276     //Setting this flag will that the first setParameter call will apply all 3A settings
277     //and will not conditionally apply based on current values.
278     mFirstTimeInit = true;
279 
280     memset(mExposureBracketingValues, 0, EXP_BRACKET_RANGE*sizeof(int));
281     mMeasurementEnabled = false;
282     mFaceDetectionRunning = false;
283     mFaceDetectionPaused = false;
284 
285     memset(&mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex], 0, sizeof(OMXCameraPortParameters));
286     memset(&mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex], 0, sizeof(OMXCameraPortParameters));
287 
288     //Initialize 3A defaults
289     ret = apply3ADefaults(mParameters3A);
290     if ( NO_ERROR != ret ) {
291         CAMHAL_LOGEA("Couldn't apply 3A defaults!");
292         goto EXIT;
293     }
294 
295     LOG_FUNCTION_NAME_EXIT;
296     return ErrorUtils::omxToAndroidError(eError);
297 
298     EXIT:
299 
300     CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
301     performCleanupAfterError();
302     LOG_FUNCTION_NAME_EXIT;
303     return ErrorUtils::omxToAndroidError(eError);
304 }
305 
performCleanupAfterError()306 void OMXCameraAdapter::performCleanupAfterError()
307 {
308     if(mCameraAdapterParameters.mHandleComp)
309         {
310         ///Free the OMX component handle in case of error
311         OMX_FreeHandle(mCameraAdapterParameters.mHandleComp);
312         mCameraAdapterParameters.mHandleComp = NULL;
313         }
314 
315     ///De-init the OMX
316     OMX_Deinit();
317     mComponentState = OMX_StateInvalid;
318 }
319 
getPortParams(CameraFrame::FrameType frameType)320 OMXCameraAdapter::OMXCameraPortParameters *OMXCameraAdapter::getPortParams(CameraFrame::FrameType frameType)
321 {
322     OMXCameraAdapter::OMXCameraPortParameters *ret = NULL;
323 
324     switch ( frameType )
325     {
326     case CameraFrame::IMAGE_FRAME:
327     case CameraFrame::RAW_FRAME:
328         ret = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
329         break;
330     case CameraFrame::PREVIEW_FRAME_SYNC:
331     case CameraFrame::SNAPSHOT_FRAME:
332     case CameraFrame::VIDEO_FRAME_SYNC:
333         ret = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex];
334         break;
335     case CameraFrame::FRAME_DATA_SYNC:
336         ret = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mMeasurementPortIndex];
337         break;
338     default:
339         break;
340     };
341 
342     return ret;
343 }
344 
fillThisBuffer(void * frameBuf,CameraFrame::FrameType frameType)345 status_t OMXCameraAdapter::fillThisBuffer(void* frameBuf, CameraFrame::FrameType frameType)
346 {
347     status_t ret = NO_ERROR;
348     OMXCameraPortParameters *port = NULL;
349     OMX_ERRORTYPE eError = OMX_ErrorNone;
350     BaseCameraAdapter::AdapterState state;
351     BaseCameraAdapter::getState(state);
352 
353     if ( ( PREVIEW_ACTIVE & state ) != PREVIEW_ACTIVE )
354         {
355         return NO_INIT;
356         }
357 
358     if ( NULL == frameBuf )
359         {
360         return -EINVAL;
361         }
362 
363     if ( (NO_ERROR == ret) &&
364          ((CameraFrame::IMAGE_FRAME == frameType) || (CameraFrame::RAW_FRAME == frameType)) &&
365          (1 > mCapturedFrames) &&
366          (!mBracketingEnabled)) {
367         // Signal end of image capture
368         if ( NULL != mEndImageCaptureCallback) {
369             mEndImageCaptureCallback(mEndCaptureData);
370         }
371         return NO_ERROR;
372      }
373 
374     if ( NO_ERROR == ret )
375         {
376         port = getPortParams(frameType);
377         if ( NULL == port )
378             {
379             CAMHAL_LOGEB("Invalid frameType 0x%x", frameType);
380             ret = -EINVAL;
381             }
382         }
383 
384     if ( NO_ERROR == ret )
385         {
386 
387         for ( int i = 0 ; i < port->mNumBufs ; i++)
388             {
389             if ( port->mBufferHeader[i]->pBuffer == frameBuf )
390                 {
391                 eError = OMX_FillThisBuffer(mCameraAdapterParameters.mHandleComp, port->mBufferHeader[i]);
392                 if ( eError != OMX_ErrorNone )
393                     {
394                     CAMHAL_LOGEB("OMX_FillThisBuffer 0x%x", eError);
395                     goto EXIT;
396                     }
397                 mFramesWithDucati++;
398                 break;
399                 }
400             }
401 
402         }
403 
404     LOG_FUNCTION_NAME_EXIT;
405     return ret;
406 
407 EXIT:
408     CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
409     performCleanupAfterError();
410     //Since fillthisbuffer is called asynchronously, make sure to signal error to the app
411     mErrorNotifier->errorNotify(CAMERA_ERROR_HARD);
412     LOG_FUNCTION_NAME_EXIT;
413     return (ret | ErrorUtils::omxToAndroidError(eError));
414 }
415 
setParameters(const CameraParameters & params)416 status_t OMXCameraAdapter::setParameters(const CameraParameters &params)
417 {
418     LOG_FUNCTION_NAME;
419 
420     const char * str = NULL;
421     int mode = 0;
422     status_t ret = NO_ERROR;
423     bool updateImagePortParams = false;
424     int minFramerate, maxFramerate, frameRate;
425     const char *valstr = NULL;
426     const char *oldstr = NULL;
427     int w, h;
428     OMX_COLOR_FORMATTYPE pixFormat;
429     BaseCameraAdapter::AdapterState state;
430     BaseCameraAdapter::getState(state);
431 
432     ///@todo Include more camera parameters
433     if ( (valstr = params.getPreviewFormat()) != NULL )
434         {
435         if (strcmp(valstr, (const char *) CameraParameters::PIXEL_FORMAT_YUV422I) == 0)
436             {
437             CAMHAL_LOGDA("CbYCrY format selected");
438             pixFormat = OMX_COLOR_FormatCbYCrY;
439             }
440         else if(strcmp(valstr, (const char *) CameraParameters::PIXEL_FORMAT_YUV420SP) == 0 ||
441                 strcmp(valstr, (const char *) CameraParameters::PIXEL_FORMAT_YUV420P) == 0)
442             {
443             CAMHAL_LOGDA("YUV420SP format selected");
444             pixFormat = OMX_COLOR_FormatYUV420SemiPlanar;
445             }
446         else if(strcmp(valstr, (const char *) CameraParameters::PIXEL_FORMAT_RGB565) == 0)
447             {
448             CAMHAL_LOGDA("RGB565 format selected");
449             pixFormat = OMX_COLOR_Format16bitRGB565;
450             }
451         else
452             {
453             CAMHAL_LOGDA("Invalid format, CbYCrY format selected as default");
454             pixFormat = OMX_COLOR_FormatCbYCrY;
455             }
456         }
457     else
458         {
459         CAMHAL_LOGEA("Preview format is NULL, defaulting to CbYCrY");
460         pixFormat = OMX_COLOR_FormatCbYCrY;
461         }
462 
463     OMXCameraPortParameters *cap;
464     cap = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex];
465 
466     params.getPreviewSize(&w, &h);
467     frameRate = params.getPreviewFrameRate();
468     minFramerate = params.getInt(TICameraParameters::KEY_MINFRAMERATE);
469     maxFramerate = params.getInt(TICameraParameters::KEY_MAXFRAMERATE);
470     if ( ( 0 < minFramerate ) &&
471          ( 0 < maxFramerate ) )
472         {
473         if ( minFramerate > maxFramerate )
474             {
475              CAMHAL_LOGEA(" Min FPS set higher than MAX. So setting MIN and MAX to the higher value");
476              maxFramerate = minFramerate;
477             }
478 
479         if ( 0 >= frameRate )
480             {
481             frameRate = maxFramerate;
482             }
483 
484         if( ( cap->mMinFrameRate != minFramerate ) ||
485             ( cap->mMaxFrameRate != maxFramerate ) )
486             {
487             cap->mMinFrameRate = minFramerate;
488             cap->mMaxFrameRate = maxFramerate;
489             setVFramerate(cap->mMinFrameRate, cap->mMaxFrameRate);
490             }
491         }
492 
493     // TODO(XXX): Limiting 1080p to (24,24) or (15,15) for now. Need to remove later.
494     if ((w >= 1920) && (h >= 1080)) {
495         cap->mMaxFrameRate = cap->mMinFrameRate;
496         setVFramerate(cap->mMinFrameRate, cap->mMaxFrameRate);
497     }
498 
499     if ( 0 < frameRate )
500         {
501         cap->mColorFormat = pixFormat;
502         cap->mWidth = w;
503         cap->mHeight = h;
504         cap->mFrameRate = frameRate;
505 
506         CAMHAL_LOGVB("Prev: cap.mColorFormat = %d", (int)cap->mColorFormat);
507         CAMHAL_LOGVB("Prev: cap.mWidth = %d", (int)cap->mWidth);
508         CAMHAL_LOGVB("Prev: cap.mHeight = %d", (int)cap->mHeight);
509         CAMHAL_LOGVB("Prev: cap.mFrameRate = %d", (int)cap->mFrameRate);
510 
511         //TODO: Add an additional parameter for video resolution
512        //use preview resolution for now
513         cap = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex];
514         cap->mColorFormat = pixFormat;
515         cap->mWidth = w;
516         cap->mHeight = h;
517         cap->mFrameRate = frameRate;
518 
519         CAMHAL_LOGVB("Video: cap.mColorFormat = %d", (int)cap->mColorFormat);
520         CAMHAL_LOGVB("Video: cap.mWidth = %d", (int)cap->mWidth);
521         CAMHAL_LOGVB("Video: cap.mHeight = %d", (int)cap->mHeight);
522         CAMHAL_LOGVB("Video: cap.mFrameRate = %d", (int)cap->mFrameRate);
523 
524         ///mStride is set from setBufs() while passing the APIs
525         cap->mStride = 4096;
526         cap->mBufSize = cap->mStride * cap->mHeight;
527         }
528 
529     if ( ( cap->mWidth >= 1920 ) &&
530          ( cap->mHeight >= 1080 ) &&
531          ( cap->mFrameRate >= FRAME_RATE_FULL_HD ) &&
532          ( !mSensorOverclock ) )
533         {
534         mOMXStateSwitch = true;
535         }
536     else if ( ( ( cap->mWidth < 1920 ) ||
537                ( cap->mHeight < 1080 ) ||
538                ( cap->mFrameRate < FRAME_RATE_FULL_HD ) ) &&
539                ( mSensorOverclock ) )
540         {
541         mOMXStateSwitch = true;
542         }
543 
544     if ( (valstr = params.get(TICameraParameters::KEY_MEASUREMENT_ENABLE)) != NULL )
545         {
546         if (strcmp(valstr, (const char *) TICameraParameters::MEASUREMENT_ENABLE) == 0)
547             {
548             mMeasurementEnabled = true;
549             }
550         else if (strcmp(valstr, (const char *) TICameraParameters::MEASUREMENT_DISABLE) == 0)
551             {
552             mMeasurementEnabled = false;
553             }
554         else
555             {
556             mMeasurementEnabled = false;
557             }
558         }
559     else
560         {
561         //Disable measurement data by default
562         mMeasurementEnabled = false;
563         }
564 
565     ret |= setParametersCapture(params, state);
566 
567     ret |= setParameters3A(params, state);
568 
569     ret |= setParametersAlgo(params, state);
570 
571     ret |= setParametersFocus(params, state);
572 
573     ret |= setParametersFD(params, state);
574 
575     ret |= setParametersZoom(params, state);
576 
577     ret |= setParametersEXIF(params, state);
578 
579     mParams = params;
580     mFirstTimeInit = false;
581 
582     LOG_FUNCTION_NAME_EXIT;
583     return ret;
584 }
585 
saveFile(unsigned char * buff,int width,int height,int format)586 void saveFile(unsigned char   *buff, int width, int height, int format) {
587     static int      counter = 1;
588     int             fd = -1;
589     char            fn[256];
590 
591     LOG_FUNCTION_NAME;
592 
593     fn[0] = 0;
594     sprintf(fn, "/preview%03d.yuv", counter);
595     fd = open(fn, O_CREAT | O_WRONLY | O_SYNC | O_TRUNC, 0777);
596     if(fd < 0) {
597         LOGE("Unable to open file %s: %s", fn, strerror(fd));
598         return;
599     }
600 
601     CAMHAL_LOGVB("Copying from 0x%x, size=%d x %d", buff, width, height);
602 
603     //method currently supports only nv12 dumping
604     int stride = width;
605     uint8_t *bf = (uint8_t*) buff;
606     for(int i=0;i<height;i++)
607         {
608         write(fd, bf, width);
609         bf += 4096;
610         }
611 
612     for(int i=0;i<height/2;i++)
613         {
614         write(fd, bf, stride);
615         bf += 4096;
616         }
617 
618     close(fd);
619 
620 
621     counter++;
622 
623     LOG_FUNCTION_NAME_EXIT;
624 }
625 
getParameters(CameraParameters & params)626 void OMXCameraAdapter::getParameters(CameraParameters& params)
627 {
628     status_t ret = NO_ERROR;
629     OMX_CONFIG_EXPOSUREVALUETYPE exp;
630     OMX_ERRORTYPE eError = OMX_ErrorNone;
631     BaseCameraAdapter::AdapterState state;
632     BaseCameraAdapter::getState(state);
633     const char *valstr = NULL;
634     LOG_FUNCTION_NAME;
635 
636     if( mParameters3A.SceneMode != OMX_Manual ) {
637        const char *valstr_supported = NULL;
638 
639        // if preview is not started...we still need to feedback the proper params
640        // look up the settings in the LUT
641        if (((state & PREVIEW_ACTIVE) == 0) && mCapabilities) {
642            const SceneModesEntry* entry = NULL;
643            entry = getSceneModeEntry(mCapabilities->get(CameraProperties::CAMERA_NAME),
644                                     (OMX_SCENEMODETYPE) mParameters3A.SceneMode);
645            if(entry) {
646                mParameters3A.Focus = entry->focus;
647                mParameters3A.FlashMode = entry->flash;
648                mParameters3A.WhiteBallance = entry->wb;
649            }
650        }
651 
652        valstr = getLUTvalue_OMXtoHAL(mParameters3A.WhiteBallance, WBalLUT);
653        valstr_supported = mParams.get(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE);
654        if (valstr && valstr_supported && strstr(valstr_supported, valstr))
655            params.set(CameraParameters::KEY_WHITE_BALANCE , valstr);
656 
657        valstr = getLUTvalue_OMXtoHAL(mParameters3A.FlashMode, FlashLUT);
658        valstr_supported = mParams.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES);
659        if (valstr && valstr_supported && strstr(valstr_supported, valstr))
660            params.set(CameraParameters::KEY_FLASH_MODE, valstr);
661 
662        if ((mParameters3A.Focus == OMX_IMAGE_FocusControlAuto) &&
663            (mCapMode != OMXCameraAdapter::VIDEO_MODE)) {
664            valstr = CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
665        } else {
666            valstr = getLUTvalue_OMXtoHAL(mParameters3A.Focus, FocusLUT);
667        }
668        valstr_supported = mParams.get(CameraParameters::KEY_SUPPORTED_FOCUS_MODES);
669        if (valstr && valstr_supported && strstr(valstr_supported, valstr))
670            params.set(CameraParameters::KEY_FOCUS_MODE, valstr);
671     }
672 
673     //Query focus distances only when focus is running
674     if ( ( AF_ACTIVE & state ) ||
675          ( NULL == mParameters.get(CameraParameters::KEY_FOCUS_DISTANCES) ) )
676         {
677         updateFocusDistances(params);
678         }
679     else
680         {
681         params.set(CameraParameters::KEY_FOCUS_DISTANCES,
682                    mParameters.get(CameraParameters::KEY_FOCUS_DISTANCES));
683         }
684 
685     OMX_INIT_STRUCT_PTR (&exp, OMX_CONFIG_EXPOSUREVALUETYPE);
686     exp.nPortIndex = OMX_ALL;
687 
688     eError = OMX_GetConfig(mCameraAdapterParameters.mHandleComp,
689                            OMX_IndexConfigCommonExposureValue,
690                            &exp);
691     if ( OMX_ErrorNone == eError )
692         {
693         params.set(TICameraParameters::KEY_CURRENT_ISO, exp.nSensitivity);
694         }
695     else
696         {
697         CAMHAL_LOGEB("OMX error 0x%x, while retrieving current ISO value", eError);
698         }
699 
700     {
701     Mutex::Autolock lock(mZoomLock);
702     //Immediate zoom should not be avaialable while smooth zoom is running
703     if ( ZOOM_ACTIVE & state )
704         {
705         if ( mZoomParameterIdx != mCurrentZoomIdx )
706             {
707             mZoomParameterIdx += mZoomInc;
708             }
709         params.set( CameraParameters::KEY_ZOOM, mZoomParameterIdx);
710         if ( ( mCurrentZoomIdx == mTargetZoomIdx ) &&
711              ( mZoomParameterIdx == mCurrentZoomIdx ) )
712             {
713 
714             if ( NO_ERROR == ret )
715                 {
716 
717                 ret =  BaseCameraAdapter::setState(CAMERA_STOP_SMOOTH_ZOOM);
718 
719                 if ( NO_ERROR == ret )
720                     {
721                     ret = BaseCameraAdapter::commitState();
722                     }
723                 else
724                     {
725                     ret |= BaseCameraAdapter::rollbackState();
726                     }
727 
728                 }
729 
730             }
731 
732         CAMHAL_LOGDB("CameraParameters Zoom = %d", mCurrentZoomIdx);
733         }
734     else
735         {
736         params.set( CameraParameters::KEY_ZOOM, mCurrentZoomIdx);
737         }
738     }
739 
740     //Populate current lock status
741     if( (valstr = mParams.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK)) != NULL )
742       {
743         CAMHAL_LOGDB("Auto Exposure Lock get %s", mParams.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK));
744         params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK, valstr);
745       }
746 
747     if( (valstr = mParams.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK)) != NULL )
748       {
749         CAMHAL_LOGDB("Auto WhiteBalance Lock get %s", mParams.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK));
750         params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK, valstr);
751       }
752 
753 
754     LOG_FUNCTION_NAME_EXIT;
755 }
756 
setFormat(OMX_U32 port,OMXCameraPortParameters & portParams)757 status_t OMXCameraAdapter::setFormat(OMX_U32 port, OMXCameraPortParameters &portParams)
758 {
759     size_t bufferCount;
760 
761     LOG_FUNCTION_NAME;
762 
763     OMX_ERRORTYPE eError = OMX_ErrorNone;
764     OMX_PARAM_PORTDEFINITIONTYPE portCheck;
765 
766     OMX_INIT_STRUCT_PTR (&portCheck, OMX_PARAM_PORTDEFINITIONTYPE);
767 
768     portCheck.nPortIndex = port;
769 
770     eError = OMX_GetParameter (mCameraAdapterParameters.mHandleComp,
771                                 OMX_IndexParamPortDefinition, &portCheck);
772     if(eError!=OMX_ErrorNone)
773         {
774         CAMHAL_LOGEB("OMX_GetParameter - %x", eError);
775         }
776     GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
777 
778     if ( OMX_CAMERA_PORT_VIDEO_OUT_PREVIEW == port )
779         {
780         portCheck.format.video.nFrameWidth      = portParams.mWidth;
781         portCheck.format.video.nFrameHeight     = portParams.mHeight;
782         portCheck.format.video.eColorFormat     = portParams.mColorFormat;
783         portCheck.format.video.nStride          = portParams.mStride;
784         if( ( portCheck.format.video.nFrameWidth >= 1920 ) &&
785             ( portCheck.format.video.nFrameHeight >= 1080 ) &&
786             ( portParams.mFrameRate >= FRAME_RATE_FULL_HD ) )
787             {
788             setSensorOverclock(true);
789             }
790         else
791             {
792             setSensorOverclock(false);
793             }
794 
795         portCheck.format.video.xFramerate       = portParams.mFrameRate<<16;
796         portCheck.nBufferSize                   = portParams.mStride * portParams.mHeight;
797         portCheck.nBufferCountActual = portParams.mNumBufs;
798         mFocusThreshold = FOCUS_THRESHOLD * portParams.mFrameRate;
799         }
800     else if ( OMX_CAMERA_PORT_IMAGE_OUT_IMAGE == port )
801         {
802         portCheck.format.image.nFrameWidth      = portParams.mWidth;
803         portCheck.format.image.nFrameHeight     = portParams.mHeight;
804         if ( OMX_COLOR_FormatUnused == portParams.mColorFormat && mCodingMode == CodingNone )
805             {
806             portCheck.format.image.eColorFormat     = OMX_COLOR_FormatCbYCrY;
807             portCheck.format.image.eCompressionFormat = OMX_IMAGE_CodingJPEG;
808             }
809         else if ( OMX_COLOR_FormatUnused == portParams.mColorFormat && mCodingMode == CodingJPS )
810             {
811             portCheck.format.image.eColorFormat       = OMX_COLOR_FormatCbYCrY;
812             portCheck.format.image.eCompressionFormat = (OMX_IMAGE_CODINGTYPE) OMX_TI_IMAGE_CodingJPS;
813             }
814         else if ( OMX_COLOR_FormatUnused == portParams.mColorFormat && mCodingMode == CodingMPO )
815             {
816             portCheck.format.image.eColorFormat       = OMX_COLOR_FormatCbYCrY;
817             portCheck.format.image.eCompressionFormat = (OMX_IMAGE_CODINGTYPE) OMX_TI_IMAGE_CodingMPO;
818             }
819         else if ( OMX_COLOR_FormatUnused == portParams.mColorFormat && mCodingMode == CodingRAWJPEG )
820             {
821             //TODO: OMX_IMAGE_CodingJPEG should be changed to OMX_IMAGE_CodingRAWJPEG when
822             // RAW format is supported
823             portCheck.format.image.eColorFormat       = OMX_COLOR_FormatCbYCrY;
824             portCheck.format.image.eCompressionFormat = OMX_IMAGE_CodingJPEG;
825             }
826         else if ( OMX_COLOR_FormatUnused == portParams.mColorFormat && mCodingMode == CodingRAWMPO )
827             {
828             //TODO: OMX_IMAGE_CodingJPEG should be changed to OMX_IMAGE_CodingRAWMPO when
829             // RAW format is supported
830             portCheck.format.image.eColorFormat       = OMX_COLOR_FormatCbYCrY;
831             portCheck.format.image.eCompressionFormat = OMX_IMAGE_CodingJPEG;
832             }
833         else
834             {
835             portCheck.format.image.eColorFormat     = portParams.mColorFormat;
836             portCheck.format.image.eCompressionFormat = OMX_IMAGE_CodingUnused;
837             }
838 
839         //Stride for 1D tiler buffer is zero
840         portCheck.format.image.nStride          =  0;
841         portCheck.nBufferSize                   =  portParams.mStride * portParams.mWidth * portParams.mHeight;
842         portCheck.nBufferCountActual = portParams.mNumBufs;
843         }
844     else
845         {
846         CAMHAL_LOGEB("Unsupported port index 0x%x", (unsigned int)port);
847         }
848 
849     eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp,
850                             OMX_IndexParamPortDefinition, &portCheck);
851     if(eError!=OMX_ErrorNone)
852         {
853         CAMHAL_LOGEB("OMX_SetParameter - %x", eError);
854         }
855     GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
856 
857     /* check if parameters are set correctly by calling GetParameter() */
858     eError = OMX_GetParameter(mCameraAdapterParameters.mHandleComp,
859                                         OMX_IndexParamPortDefinition, &portCheck);
860     if(eError!=OMX_ErrorNone)
861         {
862         CAMHAL_LOGEB("OMX_GetParameter - %x", eError);
863         }
864     GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
865 
866     portParams.mBufSize = portCheck.nBufferSize;
867 
868     if ( OMX_CAMERA_PORT_IMAGE_OUT_IMAGE == port )
869         {
870         CAMHAL_LOGDB("\n *** IMG Width = %ld", portCheck.format.image.nFrameWidth);
871         CAMHAL_LOGDB("\n ***IMG Height = %ld", portCheck.format.image.nFrameHeight);
872 
873         CAMHAL_LOGDB("\n ***IMG IMG FMT = %x", portCheck.format.image.eColorFormat);
874         CAMHAL_LOGDB("\n ***IMG portCheck.nBufferSize = %ld\n",portCheck.nBufferSize);
875         CAMHAL_LOGDB("\n ***IMG portCheck.nBufferCountMin = %ld\n",
876                                                 portCheck.nBufferCountMin);
877         CAMHAL_LOGDB("\n ***IMG portCheck.nBufferCountActual = %ld\n",
878                                                 portCheck.nBufferCountActual);
879         CAMHAL_LOGDB("\n ***IMG portCheck.format.image.nStride = %ld\n",
880                                                 portCheck.format.image.nStride);
881         }
882     else
883         {
884         CAMHAL_LOGDB("\n *** PRV Width = %ld", portCheck.format.video.nFrameWidth);
885         CAMHAL_LOGDB("\n ***PRV Height = %ld", portCheck.format.video.nFrameHeight);
886 
887         CAMHAL_LOGDB("\n ***PRV IMG FMT = %x", portCheck.format.video.eColorFormat);
888         CAMHAL_LOGDB("\n ***PRV portCheck.nBufferSize = %ld\n",portCheck.nBufferSize);
889         CAMHAL_LOGDB("\n ***PRV portCheck.nBufferCountMin = %ld\n",
890                                                 portCheck.nBufferCountMin);
891         CAMHAL_LOGDB("\n ***PRV portCheck.nBufferCountActual = %ld\n",
892                                                 portCheck.nBufferCountActual);
893         CAMHAL_LOGDB("\n ***PRV portCheck.format.video.nStride = %ld\n",
894                                                 portCheck.format.video.nStride);
895         }
896 
897     LOG_FUNCTION_NAME_EXIT;
898 
899     return ErrorUtils::omxToAndroidError(eError);
900 
901     EXIT:
902 
903     CAMHAL_LOGEB("Exiting function %s because of eError=%x", __FUNCTION__, eError);
904 
905     LOG_FUNCTION_NAME_EXIT;
906 
907     return ErrorUtils::omxToAndroidError(eError);
908 }
909 
flushBuffers()910 status_t OMXCameraAdapter::flushBuffers()
911 {
912     status_t ret = NO_ERROR;
913     OMX_ERRORTYPE eError = OMX_ErrorNone;
914     TIMM_OSAL_ERRORTYPE err;
915     TIMM_OSAL_U32 uRequestedEvents = OMXCameraAdapter::CAMERA_PORT_FLUSH;
916     TIMM_OSAL_U32 pRetrievedEvents;
917 
918     if ( 0 != mFlushSem.Count() )
919         {
920         CAMHAL_LOGEB("Error mFlushSem semaphore count %d", mFlushSem.Count());
921         LOG_FUNCTION_NAME_EXIT;
922         return NO_INIT;
923         }
924 
925     LOG_FUNCTION_NAME;
926 
927     OMXCameraPortParameters * mPreviewData = NULL;
928     mPreviewData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex];
929 
930     ///Register for the FLUSH event
931     ///This method just inserts a message in Event Q, which is checked in the callback
932     ///The sempahore passed is signalled by the callback
933     ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
934                                 OMX_EventCmdComplete,
935                                 OMX_CommandFlush,
936                                 OMX_CAMERA_PORT_VIDEO_OUT_PREVIEW,
937                                 mFlushSem);
938     if(ret!=NO_ERROR)
939         {
940         CAMHAL_LOGEB("Error in registering for event %d", ret);
941         goto EXIT;
942         }
943 
944     ///Send FLUSH command to preview port
945     eError = OMX_SendCommand (mCameraAdapterParameters.mHandleComp,
946                               OMX_CommandFlush,
947                               mCameraAdapterParameters.mPrevPortIndex,
948                               NULL);
949 
950     if(eError!=OMX_ErrorNone)
951         {
952         CAMHAL_LOGEB("OMX_SendCommand(OMX_CommandFlush)-0x%x", eError);
953         }
954     GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
955 
956     CAMHAL_LOGDA("Waiting for flush event");
957 
958     ///Wait for the FLUSH event to occur
959     ret = mFlushSem.WaitTimeout(OMX_CMD_TIMEOUT);
960 
961     //If somethiing bad happened while we wait
962     if (mComponentState == OMX_StateInvalid)
963       {
964         CAMHAL_LOGEA("Invalid State after Flush Exitting!!!");
965         goto EXIT;
966       }
967 
968     if ( NO_ERROR == ret )
969         {
970         CAMHAL_LOGDA("Flush event received");
971         }
972     else
973         {
974         ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
975                            OMX_EventCmdComplete,
976                            OMX_CommandFlush,
977                            OMX_CAMERA_PORT_VIDEO_OUT_PREVIEW,
978                            NULL);
979         CAMHAL_LOGDA("Flush event timeout expired");
980         goto EXIT;
981         }
982 
983     LOG_FUNCTION_NAME_EXIT;
984 
985     return (ret | ErrorUtils::omxToAndroidError(eError));
986 
987     EXIT:
988     CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
989     performCleanupAfterError();
990     LOG_FUNCTION_NAME_EXIT;
991     return (ret | ErrorUtils::omxToAndroidError(eError));
992 }
993 
994 ///API to give the buffers to Adapter
useBuffers(CameraMode mode,void * bufArr,int num,size_t length,unsigned int queueable)995 status_t OMXCameraAdapter::useBuffers(CameraMode mode, void* bufArr, int num, size_t length, unsigned int queueable)
996 {
997     OMX_ERRORTYPE eError = OMX_ErrorNone;
998     status_t ret = NO_ERROR;
999 
1000     LOG_FUNCTION_NAME;
1001 
1002     switch(mode)
1003         {
1004         case CAMERA_PREVIEW:
1005             mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex].mNumBufs =  num;
1006             mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex].mMaxQueueable = queueable;
1007             ret = UseBuffersPreview(bufArr, num);
1008             break;
1009 
1010         case CAMERA_IMAGE_CAPTURE:
1011             mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex].mNumBufs = num;
1012             mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex].mMaxQueueable = queueable;
1013             ret = UseBuffersCapture(bufArr, num);
1014             break;
1015 
1016         case CAMERA_VIDEO:
1017             mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex].mNumBufs =  num;
1018             mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex].mMaxQueueable = queueable;
1019             ret = UseBuffersPreview(bufArr, num);
1020             break;
1021 
1022         case CAMERA_MEASUREMENT:
1023             mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mMeasurementPortIndex].mNumBufs = num;
1024             mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mMeasurementPortIndex].mMaxQueueable = queueable;
1025             ret = UseBuffersPreviewData(bufArr, num);
1026             break;
1027 
1028         }
1029 
1030     LOG_FUNCTION_NAME_EXIT;
1031 
1032     return ret;
1033 }
1034 
UseBuffersPreviewData(void * bufArr,int num)1035 status_t OMXCameraAdapter::UseBuffersPreviewData(void* bufArr, int num)
1036 {
1037     status_t ret = NO_ERROR;
1038     OMX_ERRORTYPE eError = OMX_ErrorNone;
1039     OMXCameraPortParameters * measurementData = NULL;
1040     uint32_t *buffers;
1041     Mutex::Autolock lock( mPreviewDataBufferLock);
1042 
1043     LOG_FUNCTION_NAME;
1044 
1045     if ( mComponentState != OMX_StateLoaded )
1046         {
1047         CAMHAL_LOGEA("Calling UseBuffersPreviewData() when not in LOADED state");
1048         return BAD_VALUE;
1049         }
1050 
1051     if ( NULL == bufArr )
1052         {
1053         CAMHAL_LOGEA("NULL pointer passed for buffArr");
1054         return BAD_VALUE;
1055         }
1056 
1057     if ( 0 != mUsePreviewDataSem.Count() )
1058         {
1059         CAMHAL_LOGEB("Error mUsePreviewDataSem semaphore count %d", mUsePreviewDataSem.Count());
1060         LOG_FUNCTION_NAME_EXIT;
1061         return NO_INIT;
1062         }
1063 
1064     if ( NO_ERROR == ret )
1065         {
1066         measurementData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mMeasurementPortIndex];
1067         measurementData->mNumBufs = num ;
1068         buffers= (uint32_t*) bufArr;
1069         }
1070 
1071     if ( NO_ERROR == ret )
1072         {
1073          ///Register for port enable event on measurement port
1074         ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
1075                                       OMX_EventCmdComplete,
1076                                       OMX_CommandPortEnable,
1077                                       mCameraAdapterParameters.mMeasurementPortIndex,
1078                                       mUsePreviewDataSem);
1079 
1080         if ( ret == NO_ERROR )
1081             {
1082             CAMHAL_LOGDB("Registering for event %d", ret);
1083             }
1084         else
1085             {
1086             CAMHAL_LOGEB("Error in registering for event %d", ret);
1087             goto EXIT;
1088             }
1089         }
1090 
1091     if ( NO_ERROR == ret )
1092         {
1093          ///Enable MEASUREMENT Port
1094          eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
1095                                       OMX_CommandPortEnable,
1096                                       mCameraAdapterParameters.mMeasurementPortIndex,
1097                                       NULL);
1098 
1099             if ( eError == OMX_ErrorNone )
1100                 {
1101                 CAMHAL_LOGDB("OMX_SendCommand(OMX_CommandPortEnable) -0x%x", eError);
1102                 }
1103             else
1104                 {
1105                 CAMHAL_LOGEB("OMX_SendCommand(OMX_CommandPortEnable) -0x%x", eError);
1106                 goto EXIT;
1107                 }
1108         }
1109 
1110     if ( NO_ERROR == ret )
1111         {
1112         ret = mUsePreviewDataSem.WaitTimeout(OMX_CMD_TIMEOUT);
1113 
1114         //If somethiing bad happened while we wait
1115         if (mComponentState == OMX_StateInvalid)
1116           {
1117             CAMHAL_LOGEA("Invalid State after measurement port enable Exitting!!!");
1118             goto EXIT;
1119           }
1120 
1121         if ( NO_ERROR == ret )
1122             {
1123             CAMHAL_LOGDA("Port enable event arrived on measurement port");
1124             }
1125         else
1126             {
1127             ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
1128                                OMX_EventCmdComplete,
1129                                OMX_CommandPortEnable,
1130                                mCameraAdapterParameters.mMeasurementPortIndex,
1131                                NULL);
1132             CAMHAL_LOGEA("Timeout expoired during port enable on measurement port");
1133             goto EXIT;
1134             }
1135 
1136         CAMHAL_LOGDA("Port enable event arrived on measurement port");
1137         }
1138 
1139     LOG_FUNCTION_NAME_EXIT;
1140 
1141     return ret;
1142 EXIT:
1143     CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
1144     performCleanupAfterError();
1145     LOG_FUNCTION_NAME_EXIT;
1146     return (ret | ErrorUtils::omxToAndroidError(eError));
1147 }
1148 
switchToExecuting()1149 status_t OMXCameraAdapter::switchToExecuting()
1150 {
1151   status_t ret = NO_ERROR;
1152   TIUTILS::Message msg;
1153 
1154   LOG_FUNCTION_NAME;
1155 
1156   mStateSwitchLock.lock();
1157   msg.command = CommandHandler::CAMERA_SWITCH_TO_EXECUTING;
1158   msg.arg1 = mErrorNotifier;
1159   ret = mCommandHandler->put(&msg);
1160 
1161   LOG_FUNCTION_NAME;
1162 
1163   return ret;
1164 }
1165 
doSwitchToExecuting()1166 status_t OMXCameraAdapter::doSwitchToExecuting()
1167 {
1168   status_t ret = NO_ERROR;
1169   OMX_ERRORTYPE eError = OMX_ErrorNone;
1170   LOG_FUNCTION_NAME;
1171 
1172   if ( (mComponentState == OMX_StateExecuting) || (mComponentState == OMX_StateInvalid) ){
1173     CAMHAL_LOGDA("Already in OMX_Executing state or OMX_StateInvalid state");
1174     mStateSwitchLock.unlock();
1175     return NO_ERROR;
1176   }
1177 
1178   if ( 0 != mSwitchToExecSem.Count() ){
1179     CAMHAL_LOGEB("Error mSwitchToExecSem semaphore count %d", mSwitchToExecSem.Count());
1180     goto EXIT;
1181   }
1182 
1183   ///Register for Preview port DISABLE  event
1184   ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
1185                          OMX_EventCmdComplete,
1186                          OMX_CommandPortDisable,
1187                          mCameraAdapterParameters.mPrevPortIndex,
1188                          mSwitchToExecSem);
1189   if ( NO_ERROR != ret ){
1190     CAMHAL_LOGEB("Error in registering Port Disable for event %d", ret);
1191     goto EXIT;
1192   }
1193   ///Disable Preview Port
1194   eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
1195                            OMX_CommandPortDisable,
1196                            mCameraAdapterParameters.mPrevPortIndex,
1197                            NULL);
1198   ret = mSwitchToExecSem.WaitTimeout(OMX_CMD_TIMEOUT);
1199   if (ret != NO_ERROR){
1200     CAMHAL_LOGEB("Timeout PREVIEW PORT DISABLE %d", ret);
1201   }
1202 
1203   CAMHAL_LOGVB("PREV PORT DISABLED %d", ret);
1204 
1205   ///Register for IDLE state switch event
1206   ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
1207                          OMX_EventCmdComplete,
1208                          OMX_CommandStateSet,
1209                          OMX_StateIdle,
1210                          mSwitchToExecSem);
1211   if(ret!=NO_ERROR)
1212     {
1213       CAMHAL_LOGEB("Error in IDLE STATE SWITCH %d", ret);
1214       goto EXIT;
1215     }
1216   eError = OMX_SendCommand (mCameraAdapterParameters.mHandleComp ,
1217                             OMX_CommandStateSet,
1218                             OMX_StateIdle,
1219                             NULL);
1220   GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1221   ret = mSwitchToExecSem.WaitTimeout(OMX_CMD_TIMEOUT);
1222   if (ret != NO_ERROR){
1223     CAMHAL_LOGEB("Timeout IDLE STATE SWITCH %d", ret);
1224     goto EXIT;
1225   }
1226   mComponentState = OMX_StateIdle;
1227   CAMHAL_LOGVB("OMX_SendCommand(OMX_StateIdle) 0x%x", eError);
1228 
1229   ///Register for EXECUTING state switch event
1230   ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
1231                          OMX_EventCmdComplete,
1232                          OMX_CommandStateSet,
1233                          OMX_StateExecuting,
1234                          mSwitchToExecSem);
1235   if(ret!=NO_ERROR)
1236     {
1237       CAMHAL_LOGEB("Error in EXECUTING STATE SWITCH %d", ret);
1238       goto EXIT;
1239     }
1240   eError = OMX_SendCommand (mCameraAdapterParameters.mHandleComp ,
1241                             OMX_CommandStateSet,
1242                             OMX_StateExecuting,
1243                             NULL);
1244   GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1245   ret = mSwitchToExecSem.WaitTimeout(OMX_CMD_TIMEOUT);
1246   if (ret != NO_ERROR){
1247     CAMHAL_LOGEB("Timeout EXEC STATE SWITCH %d", ret);
1248     goto EXIT;
1249   }
1250   mComponentState = OMX_StateExecuting;
1251   CAMHAL_LOGVB("OMX_SendCommand(OMX_StateExecuting) 0x%x", eError);
1252 
1253   mStateSwitchLock.unlock();
1254 
1255   LOG_FUNCTION_NAME_EXIT;
1256   return ret;
1257 
1258  EXIT:
1259   CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
1260   performCleanupAfterError();
1261   mStateSwitchLock.unlock();
1262   LOG_FUNCTION_NAME_EXIT;
1263   return (ret | ErrorUtils::omxToAndroidError(eError));
1264 }
1265 
switchToLoaded()1266 status_t OMXCameraAdapter::switchToLoaded()
1267 {
1268     status_t ret = NO_ERROR;
1269     OMX_ERRORTYPE eError = OMX_ErrorNone;
1270 
1271     LOG_FUNCTION_NAME;
1272 
1273     Mutex::Autolock lock(mStateSwitchLock);
1274 
1275     if ( mComponentState == OMX_StateLoaded  || mComponentState == OMX_StateInvalid)
1276         {
1277         CAMHAL_LOGDA("Already in OMX_Loaded state or OMX_StateInvalid state");
1278         return NO_ERROR;
1279         }
1280 
1281     if ( 0 != mSwitchToLoadedSem.Count() )
1282         {
1283         CAMHAL_LOGEB("Error mSwitchToLoadedSem semaphore count %d", mSwitchToLoadedSem.Count());
1284         goto EXIT;
1285         }
1286 
1287     ///Register for EXECUTING state transition.
1288     ///This method just inserts a message in Event Q, which is checked in the callback
1289     ///The sempahore passed is signalled by the callback
1290     ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
1291                            OMX_EventCmdComplete,
1292                            OMX_CommandStateSet,
1293                            OMX_StateIdle,
1294                            mSwitchToLoadedSem);
1295 
1296     if(ret!=NO_ERROR)
1297         {
1298         CAMHAL_LOGEB("Error in registering for event %d", ret);
1299         goto EXIT;
1300         }
1301 
1302     eError = OMX_SendCommand (mCameraAdapterParameters.mHandleComp,
1303                               OMX_CommandStateSet,
1304                               OMX_StateIdle,
1305                               NULL);
1306 
1307     if(eError!=OMX_ErrorNone)
1308         {
1309         CAMHAL_LOGEB("OMX_SendCommand(OMX_StateIdle) - %x", eError);
1310         }
1311 
1312     GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1313 
1314     ///Wait for the EXECUTING ->IDLE transition to arrive
1315 
1316     CAMHAL_LOGDA("EXECUTING->IDLE state changed");
1317     ret = mSwitchToLoadedSem.WaitTimeout(OMX_CMD_TIMEOUT);
1318 
1319     //If somethiing bad happened while we wait
1320     if (mComponentState == OMX_StateInvalid)
1321       {
1322         CAMHAL_LOGEA("Invalid State after EXECUTING->IDLE Exitting!!!");
1323         goto EXIT;
1324       }
1325 
1326     if ( NO_ERROR == ret )
1327         {
1328         CAMHAL_LOGDA("EXECUTING->IDLE state changed");
1329         }
1330     else
1331         {
1332         ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
1333                            OMX_EventCmdComplete,
1334                            OMX_CommandStateSet,
1335                            OMX_StateIdle,
1336                            NULL);
1337         CAMHAL_LOGEA("Timeout expired on EXECUTING->IDLE state change");
1338         goto EXIT;
1339         }
1340 
1341     ///Register for LOADED state transition.
1342     ///This method just inserts a message in Event Q, which is checked in the callback
1343     ///The sempahore passed is signalled by the callback
1344     ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
1345                            OMX_EventCmdComplete,
1346                            OMX_CommandStateSet,
1347                            OMX_StateLoaded,
1348                            mSwitchToLoadedSem);
1349 
1350     if(ret!=NO_ERROR)
1351         {
1352         CAMHAL_LOGEB("Error in registering for event %d", ret);
1353         goto EXIT;
1354         }
1355 
1356     eError = OMX_SendCommand (mCameraAdapterParameters.mHandleComp,
1357                               OMX_CommandStateSet,
1358                               OMX_StateLoaded,
1359                               NULL);
1360 
1361     if(eError!=OMX_ErrorNone)
1362         {
1363         CAMHAL_LOGEB("OMX_SendCommand(OMX_StateLoaded) - %x", eError);
1364         }
1365     GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1366 
1367     CAMHAL_LOGDA("Switching IDLE->LOADED state");
1368     ret = mSwitchToLoadedSem.WaitTimeout(OMX_CMD_TIMEOUT);
1369 
1370     //If somethiing bad happened while we wait
1371     if (mComponentState == OMX_StateInvalid)
1372       {
1373         CAMHAL_LOGEA("Invalid State after IDLE->LOADED Exitting!!!");
1374         goto EXIT;
1375       }
1376 
1377     if ( NO_ERROR == ret )
1378         {
1379         CAMHAL_LOGDA("IDLE->LOADED state changed");
1380         }
1381     else
1382         {
1383         ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
1384                            OMX_EventCmdComplete,
1385                            OMX_CommandStateSet,
1386                            OMX_StateLoaded,
1387                            NULL);
1388         CAMHAL_LOGEA("Timeout expired on IDLE->LOADED state change");
1389         goto EXIT;
1390         }
1391 
1392     mComponentState = OMX_StateLoaded;
1393 
1394     ///Register for Preview port ENABLE event
1395     ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
1396                            OMX_EventCmdComplete,
1397                            OMX_CommandPortEnable,
1398                            mCameraAdapterParameters.mPrevPortIndex,
1399                            mSwitchToLoadedSem);
1400 
1401     if ( NO_ERROR != ret )
1402         {
1403         CAMHAL_LOGEB("Error in registering for event %d", ret);
1404         goto EXIT;
1405         }
1406 
1407     ///Enable Preview Port
1408     eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
1409                              OMX_CommandPortEnable,
1410                              mCameraAdapterParameters.mPrevPortIndex,
1411                              NULL);
1412 
1413 
1414     CAMHAL_LOGDB("OMX_SendCommand(OMX_CommandStateSet) 0x%x", eError);
1415     GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1416 
1417     CAMHAL_LOGDA("Enabling Preview port");
1418     ///Wait for state to switch to idle
1419     ret = mSwitchToLoadedSem.WaitTimeout(OMX_CMD_TIMEOUT);
1420 
1421     //If somethiing bad happened while we wait
1422     if (mComponentState == OMX_StateInvalid)
1423       {
1424         CAMHAL_LOGEA("Invalid State after Enabling Preview port Exitting!!!");
1425         goto EXIT;
1426       }
1427 
1428     if ( NO_ERROR == ret )
1429         {
1430         CAMHAL_LOGDA("Preview port enabled!");
1431         }
1432     else
1433         {
1434         ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
1435                            OMX_EventCmdComplete,
1436                            OMX_CommandPortEnable,
1437                            mCameraAdapterParameters.mPrevPortIndex,
1438                            NULL);
1439         CAMHAL_LOGEA("Preview enable timedout");
1440 
1441         goto EXIT;
1442         }
1443 
1444     return (ret | ErrorUtils::omxToAndroidError(eError));
1445 
1446 EXIT:
1447     CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
1448     performCleanupAfterError();
1449     LOG_FUNCTION_NAME_EXIT;
1450     return (ret | ErrorUtils::omxToAndroidError(eError));
1451 }
1452 
UseBuffersPreview(void * bufArr,int num)1453 status_t OMXCameraAdapter::UseBuffersPreview(void* bufArr, int num)
1454 {
1455     status_t ret = NO_ERROR;
1456     OMX_ERRORTYPE eError = OMX_ErrorNone;
1457     int tmpHeight, tmpWidth;
1458 
1459     LOG_FUNCTION_NAME;
1460 
1461     ///Flag to determine whether it is 3D camera or not
1462     bool isS3d = false;
1463     const char *valstr = NULL;
1464     if ( (valstr = mParams.get(TICameraParameters::KEY_S3D_SUPPORTED)) != NULL) {
1465         isS3d = (strcmp(valstr, "true") == 0);
1466     }
1467 
1468     if(!bufArr)
1469         {
1470         CAMHAL_LOGEA("NULL pointer passed for buffArr");
1471         LOG_FUNCTION_NAME_EXIT;
1472         return BAD_VALUE;
1473         }
1474 
1475     OMXCameraPortParameters * mPreviewData = NULL;
1476     OMXCameraPortParameters *measurementData = NULL;
1477     mPreviewData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex];
1478     measurementData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mMeasurementPortIndex];
1479     mPreviewData->mNumBufs = num ;
1480     uint32_t *buffers = (uint32_t*)bufArr;
1481 
1482     if ( 0 != mUsePreviewSem.Count() )
1483         {
1484         CAMHAL_LOGEB("Error mUsePreviewSem semaphore count %d", mUsePreviewSem.Count());
1485         LOG_FUNCTION_NAME_EXIT;
1486         return NO_INIT;
1487         }
1488 
1489     if(mPreviewData->mNumBufs != num)
1490         {
1491         CAMHAL_LOGEA("Current number of buffers doesnt equal new num of buffers passed!");
1492         LOG_FUNCTION_NAME_EXIT;
1493         return BAD_VALUE;
1494         }
1495 
1496     mStateSwitchLock.lock();
1497 
1498     if ( mComponentState == OMX_StateLoaded )
1499         {
1500 
1501         ret = setLDC(mIPP);
1502         if ( NO_ERROR != ret )
1503             {
1504             CAMHAL_LOGEB("setLDC() failed %d", ret);
1505             LOG_FUNCTION_NAME_EXIT;
1506             return ret;
1507             }
1508 
1509         ret = setNSF(mIPP);
1510         if ( NO_ERROR != ret )
1511             {
1512             CAMHAL_LOGEB("setNSF() failed %d", ret);
1513             LOG_FUNCTION_NAME_EXIT;
1514             return ret;
1515             }
1516 
1517         ret = setCaptureMode(mCapMode);
1518         if ( NO_ERROR != ret )
1519             {
1520             CAMHAL_LOGEB("setCaptureMode() failed %d", ret);
1521             LOG_FUNCTION_NAME_EXIT;
1522             return ret;
1523             }
1524 
1525         CAMHAL_LOGDB("Camera Mode = %d", mCapMode);
1526 
1527         if( ( mCapMode == OMXCameraAdapter::VIDEO_MODE ) ||
1528             ( isS3d && (mCapMode == OMXCameraAdapter::HIGH_QUALITY)) )
1529             {
1530             ///Enable/Disable Video Noise Filter
1531             ret = enableVideoNoiseFilter(mVnfEnabled);
1532             if ( NO_ERROR != ret)
1533                 {
1534                 CAMHAL_LOGEB("Error configuring VNF %x", ret);
1535                 return ret;
1536                 }
1537 
1538             ///Enable/Disable Video Stabilization
1539             ret = enableVideoStabilization(mVstabEnabled);
1540             if ( NO_ERROR != ret)
1541                 {
1542                 CAMHAL_LOGEB("Error configuring VSTAB %x", ret);
1543                 return ret;
1544                 }
1545             }
1546         else
1547             {
1548             ret = enableVideoNoiseFilter(false);
1549             if ( NO_ERROR != ret)
1550                 {
1551                 CAMHAL_LOGEB("Error configuring VNF %x", ret);
1552                 return ret;
1553                 }
1554             ///Enable/Disable Video Stabilization
1555             ret = enableVideoStabilization(false);
1556             if ( NO_ERROR != ret)
1557                 {
1558                 CAMHAL_LOGEB("Error configuring VSTAB %x", ret);
1559                 return ret;
1560                 }
1561             }
1562         }
1563 
1564     ret = setSensorOrientation(mSensorOrientation);
1565     if ( NO_ERROR != ret )
1566         {
1567         CAMHAL_LOGEB("Error configuring Sensor Orientation %x", ret);
1568         mSensorOrientation = 0;
1569         }
1570 
1571     ret = setVFramerate(mPreviewData->mMinFrameRate, mPreviewData->mMaxFrameRate);
1572     if ( ret != NO_ERROR )
1573         {
1574         CAMHAL_LOGEB("VFR configuration failed 0x%x", ret);
1575         LOG_FUNCTION_NAME_EXIT;
1576         return ret;
1577         }
1578 
1579     if ( mComponentState == OMX_StateLoaded )
1580         {
1581         ///Register for IDLE state switch event
1582         ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
1583                                OMX_EventCmdComplete,
1584                                OMX_CommandStateSet,
1585                                OMX_StateIdle,
1586                                mUsePreviewSem);
1587 
1588         if(ret!=NO_ERROR)
1589             {
1590             CAMHAL_LOGEB("Error in registering for event %d", ret);
1591             goto EXIT;
1592             }
1593 
1594         ///Once we get the buffers, move component state to idle state and pass the buffers to OMX comp using UseBuffer
1595         eError = OMX_SendCommand (mCameraAdapterParameters.mHandleComp ,
1596                                   OMX_CommandStateSet,
1597                                   OMX_StateIdle,
1598                                   NULL);
1599 
1600         CAMHAL_LOGDB("OMX_SendCommand(OMX_CommandStateSet) 0x%x", eError);
1601 
1602         GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1603 
1604         mComponentState = OMX_StateIdle;
1605         }
1606     else
1607         {
1608             ///Register for Preview port ENABLE event
1609             ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
1610                                    OMX_EventCmdComplete,
1611                                    OMX_CommandPortEnable,
1612                                    mCameraAdapterParameters.mPrevPortIndex,
1613                                    mUsePreviewSem);
1614 
1615             if ( NO_ERROR != ret )
1616                 {
1617                 CAMHAL_LOGEB("Error in registering for event %d", ret);
1618                 goto EXIT;
1619                 }
1620 
1621             ///Enable Preview Port
1622             eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
1623                                      OMX_CommandPortEnable,
1624                                      mCameraAdapterParameters.mPrevPortIndex,
1625                                      NULL);
1626         }
1627 
1628 
1629     ///Configure DOMX to use either gralloc handles or vptrs
1630     OMX_TI_PARAMUSENATIVEBUFFER domxUseGrallocHandles;
1631     OMX_INIT_STRUCT_PTR (&domxUseGrallocHandles, OMX_TI_PARAMUSENATIVEBUFFER);
1632 
1633     domxUseGrallocHandles.nPortIndex = mCameraAdapterParameters.mPrevPortIndex;
1634     domxUseGrallocHandles.bEnable = OMX_TRUE;
1635 
1636     eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp,
1637                             (OMX_INDEXTYPE)OMX_TI_IndexUseNativeBuffers, &domxUseGrallocHandles);
1638     if(eError!=OMX_ErrorNone)
1639         {
1640         CAMHAL_LOGEB("OMX_SetParameter - %x", eError);
1641         }
1642     GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1643 
1644     OMX_BUFFERHEADERTYPE *pBufferHdr;
1645     for(int index=0;index<num;index++) {
1646 
1647         CAMHAL_LOGDB("OMX_UseBuffer(0x%x)", buffers[index]);
1648         eError = OMX_UseBuffer( mCameraAdapterParameters.mHandleComp,
1649                                 &pBufferHdr,
1650                                 mCameraAdapterParameters.mPrevPortIndex,
1651                                 0,
1652                                 mPreviewData->mBufSize,
1653                                 (OMX_U8*)buffers[index]);
1654         if(eError!=OMX_ErrorNone)
1655             {
1656             CAMHAL_LOGEB("OMX_UseBuffer-0x%x", eError);
1657             }
1658         GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1659 
1660         //pBufferHdr->pAppPrivate =  (OMX_PTR)pBufferHdr;
1661         pBufferHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
1662         pBufferHdr->nVersion.s.nVersionMajor = 1 ;
1663         pBufferHdr->nVersion.s.nVersionMinor = 1 ;
1664         pBufferHdr->nVersion.s.nRevision = 0 ;
1665         pBufferHdr->nVersion.s.nStep =  0;
1666         mPreviewData->mBufferHeader[index] = pBufferHdr;
1667     }
1668 
1669     if ( mMeasurementEnabled )
1670         {
1671 
1672         for( int i = 0; i < num; i++ )
1673             {
1674             OMX_BUFFERHEADERTYPE *pBufHdr;
1675             eError = OMX_UseBuffer( mCameraAdapterParameters.mHandleComp,
1676                                     &pBufHdr,
1677                                     mCameraAdapterParameters.mMeasurementPortIndex,
1678                                     0,
1679                                     measurementData->mBufSize,
1680                                     (OMX_U8*)(mPreviewDataBuffers[i]));
1681 
1682              if ( eError == OMX_ErrorNone )
1683                 {
1684                 pBufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
1685                 pBufHdr->nVersion.s.nVersionMajor = 1 ;
1686                 pBufHdr->nVersion.s.nVersionMinor = 1 ;
1687                 pBufHdr->nVersion.s.nRevision = 0 ;
1688                 pBufHdr->nVersion.s.nStep =  0;
1689                 measurementData->mBufferHeader[i] = pBufHdr;
1690                 }
1691             else
1692                 {
1693                 CAMHAL_LOGEB("OMX_UseBuffer -0x%x", eError);
1694                 ret = BAD_VALUE;
1695                 break;
1696                 }
1697             }
1698 
1699         }
1700 
1701     CAMHAL_LOGDA("Registering preview buffers");
1702 
1703     ret = mUsePreviewSem.WaitTimeout(OMX_CMD_TIMEOUT);
1704 
1705     //If somethiing bad happened while we wait
1706     if (mComponentState == OMX_StateInvalid)
1707       {
1708         CAMHAL_LOGEA("Invalid State after Registering preview buffers Exitting!!!");
1709         goto EXIT;
1710       }
1711 
1712     if ( NO_ERROR == ret )
1713         {
1714         CAMHAL_LOGDA("Preview buffer registration successfull");
1715         }
1716     else
1717         {
1718         if ( mComponentState == OMX_StateLoaded )
1719             {
1720             ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
1721                                OMX_EventCmdComplete,
1722                                OMX_CommandStateSet,
1723                                OMX_StateIdle,
1724                                NULL);
1725             }
1726         else
1727             {
1728             ret |= SignalEvent(mCameraAdapterParameters.mHandleComp,
1729                                OMX_EventCmdComplete,
1730                                OMX_CommandPortEnable,
1731                                mCameraAdapterParameters.mPrevPortIndex,
1732                                NULL);
1733             }
1734         CAMHAL_LOGEA("Timeout expired on preview buffer registration");
1735         goto EXIT;
1736         }
1737 
1738     LOG_FUNCTION_NAME_EXIT;
1739 
1740     return (ret | ErrorUtils::omxToAndroidError(eError));
1741 
1742     ///If there is any failure, we reach here.
1743     ///Here, we do any resource freeing and convert from OMX error code to Camera Hal error code
1744 EXIT:
1745     CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
1746     performCleanupAfterError();
1747     CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
1748 
1749     LOG_FUNCTION_NAME_EXIT;
1750 
1751     return (ret | ErrorUtils::omxToAndroidError(eError));
1752 }
1753 
startPreview()1754 status_t OMXCameraAdapter::startPreview()
1755 {
1756     status_t ret = NO_ERROR;
1757     OMX_ERRORTYPE eError = OMX_ErrorNone;
1758     OMXCameraPortParameters *mPreviewData = NULL;
1759     OMXCameraPortParameters *measurementData = NULL;
1760 
1761     LOG_FUNCTION_NAME;
1762 
1763     if( 0 != mStartPreviewSem.Count() )
1764         {
1765         CAMHAL_LOGEB("Error mStartPreviewSem semaphore count %d", mStartPreviewSem.Count());
1766         LOG_FUNCTION_NAME_EXIT;
1767         return NO_INIT;
1768         }
1769 
1770     mPreviewData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex];
1771     measurementData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mMeasurementPortIndex];
1772 
1773     if( OMX_StateIdle == mComponentState )
1774         {
1775         ///Register for EXECUTING state transition.
1776         ///This method just inserts a message in Event Q, which is checked in the callback
1777         ///The sempahore passed is signalled by the callback
1778         ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
1779                                OMX_EventCmdComplete,
1780                                OMX_CommandStateSet,
1781                                OMX_StateExecuting,
1782                                mStartPreviewSem);
1783 
1784         if(ret!=NO_ERROR)
1785             {
1786             CAMHAL_LOGEB("Error in registering for event %d", ret);
1787             goto EXIT;
1788             }
1789 
1790         ///Switch to EXECUTING state
1791         eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
1792                                  OMX_CommandStateSet,
1793                                  OMX_StateExecuting,
1794                                  NULL);
1795 
1796         if(eError!=OMX_ErrorNone)
1797             {
1798             CAMHAL_LOGEB("OMX_SendCommand(OMX_StateExecuting)-0x%x", eError);
1799             }
1800 
1801         CAMHAL_LOGDA("+Waiting for component to go into EXECUTING state");
1802         ret = mStartPreviewSem.WaitTimeout(OMX_CMD_TIMEOUT);
1803 
1804         //If somethiing bad happened while we wait
1805         if (mComponentState == OMX_StateInvalid)
1806           {
1807             CAMHAL_LOGEA("Invalid State after IDLE_EXECUTING Exitting!!!");
1808             goto EXIT;
1809           }
1810 
1811         if ( NO_ERROR == ret )
1812             {
1813             CAMHAL_LOGDA("+Great. Component went into executing state!!");
1814             }
1815         else
1816             {
1817             ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
1818                                OMX_EventCmdComplete,
1819                                OMX_CommandStateSet,
1820                                OMX_StateExecuting,
1821                                NULL);
1822             CAMHAL_LOGDA("Timeout expired on executing state switch!");
1823             goto EXIT;
1824             }
1825 
1826         mComponentState = OMX_StateExecuting;
1827 
1828         }
1829 
1830     mStateSwitchLock.unlock();
1831 
1832     //Queue all the buffers on preview port
1833     for(int index=0;index< mPreviewData->mMaxQueueable;index++)
1834         {
1835         CAMHAL_LOGDB("Queuing buffer on Preview port - 0x%x", (uint32_t)mPreviewData->mBufferHeader[index]->pBuffer);
1836         eError = OMX_FillThisBuffer(mCameraAdapterParameters.mHandleComp,
1837                     (OMX_BUFFERHEADERTYPE*)mPreviewData->mBufferHeader[index]);
1838         if(eError!=OMX_ErrorNone)
1839             {
1840             CAMHAL_LOGEB("OMX_FillThisBuffer-0x%x", eError);
1841             }
1842         mFramesWithDucati++;
1843 #ifdef DEGUG_LOG
1844         mBuffersWithDucati.add((uint32_t)mPreviewData->mBufferHeader[index]->pBuffer,1);
1845 #endif
1846         GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1847         }
1848 
1849     if ( mMeasurementEnabled )
1850         {
1851 
1852         for(int index=0;index< mPreviewData->mNumBufs;index++)
1853             {
1854             CAMHAL_LOGDB("Queuing buffer on Measurement port - 0x%x", (uint32_t) measurementData->mBufferHeader[index]->pBuffer);
1855             eError = OMX_FillThisBuffer(mCameraAdapterParameters.mHandleComp,
1856                             (OMX_BUFFERHEADERTYPE*) measurementData->mBufferHeader[index]);
1857             if(eError!=OMX_ErrorNone)
1858                 {
1859                 CAMHAL_LOGEB("OMX_FillThisBuffer-0x%x", eError);
1860                 }
1861             GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1862             }
1863 
1864         }
1865 
1866     if ( mPending3Asettings )
1867         apply3Asettings(mParameters3A);
1868 
1869     //reset frame rate estimates
1870     mFPS = 0.0f;
1871     mLastFPS = 0.0f;
1872     // start frame count from 0. i.e first frame after
1873     // startPreview will be the 0th reference frame
1874     // this way we will wait for second frame until
1875     // takePicture/autoFocus is allowed to run. we
1876     // are seeing SetConfig/GetConfig fail after
1877     // calling after the first frame and not failing
1878     // after the second frame
1879     mFrameCount = -1;
1880     mLastFrameCount = 0;
1881     mIter = 1;
1882     mLastFPSTime = systemTime();
1883 
1884     LOG_FUNCTION_NAME_EXIT;
1885 
1886     return (ret | ErrorUtils::omxToAndroidError(eError));
1887 
1888     EXIT:
1889 
1890     CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
1891     performCleanupAfterError();
1892     mStateSwitchLock.unlock();
1893     LOG_FUNCTION_NAME_EXIT;
1894 
1895     return (ret | ErrorUtils::omxToAndroidError(eError));
1896 
1897 }
1898 
stopPreview()1899 status_t OMXCameraAdapter::stopPreview()
1900 {
1901     LOG_FUNCTION_NAME;
1902 
1903     OMX_ERRORTYPE eError = OMX_ErrorNone;
1904     status_t ret = NO_ERROR;
1905 
1906     OMXCameraPortParameters *mCaptureData , *mPreviewData, *measurementData;
1907     mCaptureData = mPreviewData = measurementData = NULL;
1908 
1909     mPreviewData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex];
1910     mCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
1911     measurementData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mMeasurementPortIndex];
1912 
1913     if ( mComponentState != OMX_StateExecuting )
1914         {
1915         CAMHAL_LOGEA("Calling StopPreview() when not in EXECUTING state");
1916         LOG_FUNCTION_NAME_EXIT;
1917         return NO_INIT;
1918         }
1919 
1920     {
1921         Mutex::Autolock lock(mFrameCountMutex);
1922         mFrameCount = 0;
1923         mFirstFrameCondition.broadcast();
1924     }
1925 
1926     ret = cancelAutoFocus();
1927     if(ret!=NO_ERROR)
1928     {
1929         CAMHAL_LOGEB("Error canceling autofocus %d", ret);
1930         // Error, but we probably still want to continue to stop preview
1931     }
1932 
1933     OMX_CONFIG_FOCUSASSISTTYPE focusAssist;
1934     OMX_INIT_STRUCT_PTR (&focusAssist, OMX_CONFIG_FOCUSASSISTTYPE);
1935     focusAssist.nPortIndex = OMX_ALL;
1936     focusAssist.bFocusAssist = OMX_FALSE;
1937     CAMHAL_LOGDB("Configuring AF Assist mode 0x%x", focusAssist.bFocusAssist);
1938     eError =  OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
1939                             (OMX_INDEXTYPE) OMX_IndexConfigFocusAssist,
1940                             &focusAssist);
1941     if ( OMX_ErrorNone != eError )
1942         {
1943         CAMHAL_LOGEB("Error while configuring AF Assist mode 0x%x", eError);
1944         }
1945     else
1946         {
1947         CAMHAL_LOGDA("Camera AF Assist  mode configured successfully");
1948         }
1949 
1950     if ( 0 != mStopPreviewSem.Count() )
1951         {
1952         CAMHAL_LOGEB("Error mStopPreviewSem semaphore count %d", mStopPreviewSem.Count());
1953         LOG_FUNCTION_NAME_EXIT;
1954         return NO_INIT;
1955         }
1956 
1957     ret = disableImagePort();
1958     if ( NO_ERROR != ret ) {
1959         CAMHAL_LOGEB("disable image port failed 0x%x", ret);
1960         goto EXIT;
1961     }
1962 
1963     CAMHAL_LOGDB("Average framerate: %f", mFPS);
1964 
1965     //Avoid state switching of the OMX Component
1966     ret = flushBuffers();
1967     if ( NO_ERROR != ret )
1968         {
1969         CAMHAL_LOGEB("Flush Buffers failed 0x%x", ret);
1970         goto EXIT;
1971         }
1972 
1973     ///Register for Preview port Disable event
1974     ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
1975                            OMX_EventCmdComplete,
1976                            OMX_CommandPortDisable,
1977                            mCameraAdapterParameters.mPrevPortIndex,
1978                            mStopPreviewSem);
1979 
1980     ///Disable Preview Port
1981     eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
1982                              OMX_CommandPortDisable,
1983                              mCameraAdapterParameters.mPrevPortIndex,
1984                              NULL);
1985 
1986     ///Free the OMX Buffers
1987     for ( int i = 0 ; i < mPreviewData->mNumBufs ; i++ )
1988         {
1989         eError = OMX_FreeBuffer(mCameraAdapterParameters.mHandleComp,
1990                                 mCameraAdapterParameters.mPrevPortIndex,
1991                                 mPreviewData->mBufferHeader[i]);
1992 
1993         if(eError!=OMX_ErrorNone)
1994             {
1995             CAMHAL_LOGEB("OMX_FreeBuffer - %x", eError);
1996             }
1997         GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1998         }
1999 
2000     if ( mMeasurementEnabled )
2001         {
2002 
2003             for ( int i = 0 ; i < measurementData->mNumBufs ; i++ )
2004                 {
2005                 eError = OMX_FreeBuffer(mCameraAdapterParameters.mHandleComp,
2006                                         mCameraAdapterParameters.mMeasurementPortIndex,
2007                                         measurementData->mBufferHeader[i]);
2008                 if(eError!=OMX_ErrorNone)
2009                     {
2010                     CAMHAL_LOGEB("OMX_FreeBuffer - %x", eError);
2011                     }
2012                 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
2013                 }
2014 
2015             {
2016             Mutex::Autolock lock(mPreviewDataBufferLock);
2017             mPreviewDataBuffersAvailable.clear();
2018             }
2019 
2020         }
2021 
2022     CAMHAL_LOGDA("Disabling preview port");
2023     ret = mStopPreviewSem.WaitTimeout(OMX_CMD_TIMEOUT);
2024 
2025     //If somethiing bad happened while we wait
2026     if (mComponentState == OMX_StateInvalid)
2027       {
2028         CAMHAL_LOGEA("Invalid State after Disabling preview port Exitting!!!");
2029         goto EXIT;
2030       }
2031 
2032     if ( NO_ERROR == ret )
2033         {
2034         CAMHAL_LOGDA("Preview port disabled");
2035         }
2036     else
2037         {
2038         ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
2039                            OMX_EventCmdComplete,
2040                            OMX_CommandPortDisable,
2041                            mCameraAdapterParameters.mPrevPortIndex,
2042                            NULL);
2043         CAMHAL_LOGEA("Timeout expired on preview port disable");
2044         goto EXIT;
2045         }
2046 
2047         {
2048         Mutex::Autolock lock(mPreviewBufferLock);
2049         ///Clear all the available preview buffers
2050         mPreviewBuffersAvailable.clear();
2051         }
2052 
2053     switchToLoaded();
2054 
2055 
2056     mFirstTimeInit = true;
2057     mPendingCaptureSettings = 0;
2058     mFramesWithDucati = 0;
2059     mFramesWithDisplay = 0;
2060     mFramesWithEncoder = 0;
2061 
2062     LOG_FUNCTION_NAME_EXIT;
2063 
2064     return (ret | ErrorUtils::omxToAndroidError(eError));
2065 
2066 EXIT:
2067     CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
2068     {
2069     Mutex::Autolock lock(mPreviewBufferLock);
2070     ///Clear all the available preview buffers
2071     mPreviewBuffersAvailable.clear();
2072     }
2073     performCleanupAfterError();
2074     LOG_FUNCTION_NAME_EXIT;
2075     return (ret | ErrorUtils::omxToAndroidError(eError));
2076 
2077 }
2078 
setSensorOverclock(bool enable)2079 status_t OMXCameraAdapter::setSensorOverclock(bool enable)
2080 {
2081     status_t ret = NO_ERROR;
2082     OMX_ERRORTYPE eError = OMX_ErrorNone;
2083     OMX_CONFIG_BOOLEANTYPE bOMX;
2084 
2085     LOG_FUNCTION_NAME;
2086 
2087     if ( OMX_StateLoaded != mComponentState )
2088         {
2089         CAMHAL_LOGDA("OMX component is not in loaded state");
2090         return ret;
2091         }
2092 
2093     if ( NO_ERROR == ret )
2094         {
2095         OMX_INIT_STRUCT_PTR (&bOMX, OMX_CONFIG_BOOLEANTYPE);
2096 
2097         if ( enable )
2098             {
2099             bOMX.bEnabled = OMX_TRUE;
2100             }
2101         else
2102             {
2103             bOMX.bEnabled = OMX_FALSE;
2104             }
2105 
2106         CAMHAL_LOGDB("Configuring Sensor overclock mode 0x%x", bOMX.bEnabled);
2107         eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp, ( OMX_INDEXTYPE ) OMX_TI_IndexParamSensorOverClockMode, &bOMX);
2108         if ( OMX_ErrorNone != eError )
2109             {
2110             CAMHAL_LOGEB("Error while setting Sensor overclock 0x%x", eError);
2111             ret = BAD_VALUE;
2112             }
2113         else
2114             {
2115             mSensorOverclock = enable;
2116             }
2117         }
2118 
2119     LOG_FUNCTION_NAME_EXIT;
2120 
2121     return ret;
2122 }
2123 
printComponentVersion(OMX_HANDLETYPE handle)2124 status_t OMXCameraAdapter::printComponentVersion(OMX_HANDLETYPE handle)
2125 {
2126     status_t ret = NO_ERROR;
2127     OMX_ERRORTYPE eError = OMX_ErrorNone;
2128     OMX_VERSIONTYPE compVersion;
2129     char compName[OMX_MAX_STRINGNAME_SIZE];
2130     char *currentUUID = NULL;
2131     size_t offset = 0;
2132 
2133     LOG_FUNCTION_NAME;
2134 
2135     if ( NULL == handle )
2136         {
2137         CAMHAL_LOGEB("Invalid OMX Handle =0x%x",  ( unsigned int ) handle);
2138         ret = -EINVAL;
2139         }
2140 
2141     mCompUUID[0] = 0;
2142 
2143     if ( NO_ERROR == ret )
2144         {
2145         eError = OMX_GetComponentVersion(handle,
2146                                       compName,
2147                                       &compVersion,
2148                                       &mCompRevision,
2149                                       &mCompUUID
2150                                     );
2151         if ( OMX_ErrorNone != eError )
2152             {
2153             CAMHAL_LOGEB("OMX_GetComponentVersion returned 0x%x", eError);
2154             ret = BAD_VALUE;
2155             }
2156         }
2157 
2158     if ( NO_ERROR == ret )
2159         {
2160         CAMHAL_LOGVB("OMX Component name: [%s]", compName);
2161         CAMHAL_LOGVB("OMX Component version: [%u]", ( unsigned int ) compVersion.nVersion);
2162         CAMHAL_LOGVB("Spec version: [%u]", ( unsigned int ) mCompRevision.nVersion);
2163         CAMHAL_LOGVB("Git Commit ID: [%s]", mCompUUID);
2164         currentUUID = ( char * ) mCompUUID;
2165         }
2166 
2167     if ( NULL != currentUUID )
2168         {
2169         offset = strlen( ( const char * ) mCompUUID) + 1;
2170         if ( (int)currentUUID + (int)offset - (int)mCompUUID < OMX_MAX_STRINGNAME_SIZE )
2171             {
2172             currentUUID += offset;
2173             CAMHAL_LOGVB("Git Branch: [%s]", currentUUID);
2174             }
2175         else
2176             {
2177             ret = BAD_VALUE;
2178             }
2179     }
2180 
2181     if ( NO_ERROR == ret )
2182         {
2183         offset = strlen( ( const char * ) currentUUID) + 1;
2184 
2185         if ( (int)currentUUID + (int)offset - (int)mCompUUID < OMX_MAX_STRINGNAME_SIZE )
2186             {
2187             currentUUID += offset;
2188             CAMHAL_LOGVB("Build date and time: [%s]", currentUUID);
2189             }
2190         else
2191             {
2192             ret = BAD_VALUE;
2193             }
2194         }
2195 
2196     if ( NO_ERROR == ret )
2197         {
2198         offset = strlen( ( const char * ) currentUUID) + 1;
2199 
2200         if ( (int)currentUUID + (int)offset - (int)mCompUUID < OMX_MAX_STRINGNAME_SIZE )
2201             {
2202             currentUUID += offset;
2203             CAMHAL_LOGVB("Build description: [%s]", currentUUID);
2204             }
2205         else
2206             {
2207             ret = BAD_VALUE;
2208             }
2209         }
2210 
2211     LOG_FUNCTION_NAME_EXIT;
2212 
2213     return ret;
2214 }
2215 
autoFocus()2216 status_t OMXCameraAdapter::autoFocus()
2217 {
2218     status_t ret = NO_ERROR;
2219     TIUTILS::Message msg;
2220 
2221     LOG_FUNCTION_NAME;
2222 
2223     {
2224         Mutex::Autolock lock(mFrameCountMutex);
2225         if (mFrameCount < 1) {
2226             // first frame may time some time to come...so wait for an adequate amount of time
2227             // which 2 * OMX_CAPTURE_TIMEOUT * 1000 will cover.
2228             ret = mFirstFrameCondition.waitRelative(mFrameCountMutex,
2229                                                     (nsecs_t) 2 * OMX_CAPTURE_TIMEOUT * 1000);
2230             if ((NO_ERROR != ret) || (mFrameCount == 0)) {
2231                 goto EXIT;
2232             }
2233         }
2234     }
2235 
2236     msg.command = CommandHandler::CAMERA_PERFORM_AUTOFOCUS;
2237     msg.arg1 = mErrorNotifier;
2238     ret = mCommandHandler->put(&msg);
2239 
2240  EXIT:
2241 
2242     LOG_FUNCTION_NAME;
2243 
2244     return ret;
2245 }
2246 
takePicture()2247 status_t OMXCameraAdapter::takePicture()
2248 {
2249     status_t ret = NO_ERROR;
2250     TIUTILS::Message msg;
2251 
2252     LOG_FUNCTION_NAME;
2253 
2254     {
2255         Mutex::Autolock lock(mFrameCountMutex);
2256         if (mFrameCount < 1) {
2257             // first frame may time some time to come...so wait for an adequate amount of time
2258             // which 2 * OMX_CAPTURE_TIMEOUT * 1000 will cover.
2259             ret = mFirstFrameCondition.waitRelative(mFrameCountMutex,
2260                                                    (nsecs_t) 2 * OMX_CAPTURE_TIMEOUT * 1000);
2261             if ((NO_ERROR != ret) || (mFrameCount == 0)) {
2262                 goto EXIT;
2263             }
2264         }
2265     }
2266 
2267     msg.command = CommandHandler::CAMERA_START_IMAGE_CAPTURE;
2268     msg.arg1 = mErrorNotifier;
2269     ret = mCommandHandler->put(&msg);
2270 
2271  EXIT:
2272     LOG_FUNCTION_NAME_EXIT;
2273 
2274     return ret;
2275 }
2276 
startVideoCapture()2277 status_t OMXCameraAdapter::startVideoCapture()
2278 {
2279     return BaseCameraAdapter::startVideoCapture();
2280 }
2281 
stopVideoCapture()2282 status_t OMXCameraAdapter::stopVideoCapture()
2283 {
2284     return BaseCameraAdapter::stopVideoCapture();
2285 }
2286 
2287 //API to get the frame size required to be allocated. This size is used to override the size passed
2288 //by camera service when VSTAB/VNF is turned ON for example
getFrameSize(size_t & width,size_t & height)2289 status_t OMXCameraAdapter::getFrameSize(size_t &width, size_t &height)
2290 {
2291     status_t ret = NO_ERROR;
2292     OMX_ERRORTYPE eError = OMX_ErrorNone;
2293     OMX_CONFIG_RECTTYPE tFrameDim;
2294 
2295     LOG_FUNCTION_NAME;
2296 
2297     OMX_INIT_STRUCT_PTR (&tFrameDim, OMX_CONFIG_RECTTYPE);
2298     tFrameDim.nPortIndex = mCameraAdapterParameters.mPrevPortIndex;
2299 
2300     if ( mOMXStateSwitch )
2301         {
2302         ret = switchToLoaded();
2303         if ( NO_ERROR != ret )
2304             {
2305             CAMHAL_LOGEB("switchToLoaded() failed 0x%x", ret);
2306             goto exit;
2307             }
2308 
2309         mOMXStateSwitch = false;
2310         }
2311 
2312     if ( OMX_StateLoaded == mComponentState )
2313         {
2314 
2315         ret = setLDC(mIPP);
2316         if ( NO_ERROR != ret )
2317             {
2318             CAMHAL_LOGEB("setLDC() failed %d", ret);
2319             LOG_FUNCTION_NAME_EXIT;
2320             goto exit;
2321             }
2322 
2323         ret = setNSF(mIPP);
2324         if ( NO_ERROR != ret )
2325             {
2326             CAMHAL_LOGEB("setNSF() failed %d", ret);
2327             LOG_FUNCTION_NAME_EXIT;
2328             goto exit;
2329             }
2330 
2331         ret = setCaptureMode(mCapMode);
2332         if ( NO_ERROR != ret )
2333             {
2334             CAMHAL_LOGEB("setCaptureMode() failed %d", ret);
2335             }
2336 
2337         if(mCapMode == OMXCameraAdapter::VIDEO_MODE)
2338             {
2339             if ( NO_ERROR == ret )
2340                 {
2341                 ///Enable/Disable Video Noise Filter
2342                 ret = enableVideoNoiseFilter(mVnfEnabled);
2343                 }
2344 
2345             if ( NO_ERROR != ret)
2346                 {
2347                 CAMHAL_LOGEB("Error configuring VNF %x", ret);
2348                 }
2349 
2350             if ( NO_ERROR == ret )
2351                 {
2352                 ///Enable/Disable Video Stabilization
2353                 ret = enableVideoStabilization(mVstabEnabled);
2354                 }
2355 
2356             if ( NO_ERROR != ret)
2357                 {
2358                 CAMHAL_LOGEB("Error configuring VSTAB %x", ret);
2359                 }
2360              }
2361         else
2362             {
2363             if ( NO_ERROR == ret )
2364                 {
2365                 ///Enable/Disable Video Noise Filter
2366                 ret = enableVideoNoiseFilter(false);
2367                 }
2368 
2369             if ( NO_ERROR != ret)
2370                 {
2371                 CAMHAL_LOGEB("Error configuring VNF %x", ret);
2372                 }
2373 
2374             if ( NO_ERROR == ret )
2375                 {
2376                 ///Enable/Disable Video Stabilization
2377                 ret = enableVideoStabilization(false);
2378                 }
2379 
2380             if ( NO_ERROR != ret)
2381                 {
2382                 CAMHAL_LOGEB("Error configuring VSTAB %x", ret);
2383                 }
2384             }
2385 
2386         }
2387 
2388     ret = setSensorOrientation(mSensorOrientation);
2389     if ( NO_ERROR != ret )
2390         {
2391         CAMHAL_LOGEB("Error configuring Sensor Orientation %x", ret);
2392         mSensorOrientation = 0;
2393         }
2394 
2395     if ( NO_ERROR == ret )
2396         {
2397         eError = OMX_GetParameter(mCameraAdapterParameters.mHandleComp, ( OMX_INDEXTYPE ) OMX_TI_IndexParam2DBufferAllocDimension, &tFrameDim);
2398         if ( OMX_ErrorNone == eError)
2399             {
2400             width = tFrameDim.nWidth;
2401             height = tFrameDim.nHeight;
2402             }
2403         }
2404 
2405 exit:
2406 
2407     CAMHAL_LOGDB("Required frame size %dx%d", width, height);
2408     LOG_FUNCTION_NAME_EXIT;
2409 
2410     return ret;
2411 }
2412 
getFrameDataSize(size_t & dataFrameSize,size_t bufferCount)2413 status_t OMXCameraAdapter::getFrameDataSize(size_t &dataFrameSize, size_t bufferCount)
2414 {
2415     status_t ret = NO_ERROR;
2416     OMX_PARAM_PORTDEFINITIONTYPE portCheck;
2417     OMX_ERRORTYPE eError = OMX_ErrorNone;
2418 
2419     LOG_FUNCTION_NAME;
2420 
2421     if ( OMX_StateLoaded != mComponentState )
2422         {
2423         CAMHAL_LOGEA("Calling getFrameDataSize() when not in LOADED state");
2424         dataFrameSize = 0;
2425         ret = BAD_VALUE;
2426         }
2427 
2428     if ( NO_ERROR == ret  )
2429         {
2430         OMX_INIT_STRUCT_PTR(&portCheck, OMX_PARAM_PORTDEFINITIONTYPE);
2431         portCheck.nPortIndex = mCameraAdapterParameters.mMeasurementPortIndex;
2432 
2433         eError = OMX_GetParameter(mCameraAdapterParameters.mHandleComp, OMX_IndexParamPortDefinition, &portCheck);
2434         if ( OMX_ErrorNone != eError )
2435             {
2436             CAMHAL_LOGEB("OMX_GetParameter on OMX_IndexParamPortDefinition returned: 0x%x", eError);
2437             dataFrameSize = 0;
2438             ret = BAD_VALUE;
2439             }
2440         }
2441 
2442     if ( NO_ERROR == ret )
2443         {
2444         portCheck.nBufferCountActual = bufferCount;
2445         eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp, OMX_IndexParamPortDefinition, &portCheck);
2446         if ( OMX_ErrorNone != eError )
2447             {
2448             CAMHAL_LOGEB("OMX_SetParameter on OMX_IndexParamPortDefinition returned: 0x%x", eError);
2449             dataFrameSize = 0;
2450             ret = BAD_VALUE;
2451             }
2452         }
2453 
2454     if ( NO_ERROR == ret  )
2455         {
2456         eError = OMX_GetParameter(mCameraAdapterParameters.mHandleComp, OMX_IndexParamPortDefinition, &portCheck);
2457         if ( OMX_ErrorNone != eError )
2458             {
2459             CAMHAL_LOGEB("OMX_GetParameter on OMX_IndexParamPortDefinition returned: 0x%x", eError);
2460             ret = BAD_VALUE;
2461             }
2462         else
2463             {
2464             mCameraAdapterParameters.mCameraPortParams[portCheck.nPortIndex].mBufSize = portCheck.nBufferSize;
2465             dataFrameSize = portCheck.nBufferSize;
2466             }
2467         }
2468 
2469     LOG_FUNCTION_NAME_EXIT;
2470 
2471     return ret;
2472 }
2473 
onOrientationEvent(uint32_t orientation,uint32_t tilt)2474 void OMXCameraAdapter::onOrientationEvent(uint32_t orientation, uint32_t tilt)
2475 {
2476     LOG_FUNCTION_NAME;
2477 
2478     static const unsigned int DEGREES_TILT_IGNORE = 45;
2479     int device_orientation = 0;
2480     int mount_orientation = 0;
2481     const char *facing_direction = NULL;
2482 
2483     // if tilt angle is greater than DEGREES_TILT_IGNORE
2484     // we are going to ignore the orientation returned from
2485     // sensor. the orientation returned from sensor is not
2486     // reliable. Value of DEGREES_TILT_IGNORE may need adjusting
2487     if (tilt > DEGREES_TILT_IGNORE) {
2488         return;
2489     }
2490 
2491     if (mCapabilities) {
2492         if (mCapabilities->get(CameraProperties::ORIENTATION_INDEX)) {
2493             mount_orientation = atoi(mCapabilities->get(CameraProperties::ORIENTATION_INDEX));
2494         }
2495         facing_direction = mCapabilities->get(CameraProperties::FACING_INDEX);
2496     }
2497 
2498     // calculate device orientation relative to the sensor orientation
2499     // front camera display is mirrored...needs to be accounted for when orientation
2500     // is 90 or 270...since this will result in a flip on orientation otherwise
2501     if (facing_direction && !strcmp(facing_direction, TICameraParameters::FACING_FRONT) &&
2502         (orientation == 90 || orientation == 270)) {
2503         device_orientation = (orientation - mount_orientation + 360) % 360;
2504     } else {  // back-facing camera
2505         device_orientation = (orientation + mount_orientation) % 360;
2506     }
2507 
2508     if (device_orientation != mDeviceOrientation) {
2509         mDeviceOrientation = device_orientation;
2510 
2511         mFaceDetectionLock.lock();
2512         if (mFaceDetectionRunning) {
2513             // restart face detection with new rotation
2514             setFaceDetection(true, mDeviceOrientation);
2515         }
2516         mFaceDetectionLock.unlock();
2517     }
2518     CAMHAL_LOGVB("orientation = %d tilt = %d device_orientation = %d", orientation, tilt, mDeviceOrientation);
2519 
2520     LOG_FUNCTION_NAME_EXIT;
2521 }
2522 
2523 /* Application callback Functions */
2524 /*========================================================*/
2525 /* @ fn SampleTest_EventHandler :: Application callback   */
2526 /*========================================================*/
OMXCameraAdapterEventHandler(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_PTR pAppData,OMX_IN OMX_EVENTTYPE eEvent,OMX_IN OMX_U32 nData1,OMX_IN OMX_U32 nData2,OMX_IN OMX_PTR pEventData)2527 OMX_ERRORTYPE OMXCameraAdapterEventHandler(OMX_IN OMX_HANDLETYPE hComponent,
2528                                           OMX_IN OMX_PTR pAppData,
2529                                           OMX_IN OMX_EVENTTYPE eEvent,
2530                                           OMX_IN OMX_U32 nData1,
2531                                           OMX_IN OMX_U32 nData2,
2532                                           OMX_IN OMX_PTR pEventData)
2533 {
2534     LOG_FUNCTION_NAME;
2535 
2536     CAMHAL_LOGDB("Event %d", eEvent);
2537 
2538     OMX_ERRORTYPE ret = OMX_ErrorNone;
2539     OMXCameraAdapter *oca = (OMXCameraAdapter*)pAppData;
2540     ret = oca->OMXCameraAdapterEventHandler(hComponent, eEvent, nData1, nData2, pEventData);
2541 
2542     LOG_FUNCTION_NAME_EXIT;
2543     return ret;
2544 }
2545 
2546 /* Application callback Functions */
2547 /*========================================================*/
2548 /* @ fn SampleTest_EventHandler :: Application callback   */
2549 /*========================================================*/
OMXCameraAdapterEventHandler(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_EVENTTYPE eEvent,OMX_IN OMX_U32 nData1,OMX_IN OMX_U32 nData2,OMX_IN OMX_PTR pEventData)2550 OMX_ERRORTYPE OMXCameraAdapter::OMXCameraAdapterEventHandler(OMX_IN OMX_HANDLETYPE hComponent,
2551                                           OMX_IN OMX_EVENTTYPE eEvent,
2552                                           OMX_IN OMX_U32 nData1,
2553                                           OMX_IN OMX_U32 nData2,
2554                                           OMX_IN OMX_PTR pEventData)
2555 {
2556 
2557     LOG_FUNCTION_NAME;
2558 
2559     OMX_ERRORTYPE eError = OMX_ErrorNone;
2560     CAMHAL_LOGDB("+OMX_Event %x, %d %d", eEvent, (int)nData1, (int)nData2);
2561 
2562     switch (eEvent) {
2563         case OMX_EventCmdComplete:
2564             CAMHAL_LOGDB("+OMX_EventCmdComplete %d %d", (int)nData1, (int)nData2);
2565 
2566             if (OMX_CommandStateSet == nData1) {
2567                 mCameraAdapterParameters.mState = (OMX_STATETYPE) nData2;
2568 
2569             } else if (OMX_CommandFlush == nData1) {
2570                 CAMHAL_LOGDB("OMX_CommandFlush received for port %d", (int)nData2);
2571 
2572             } else if (OMX_CommandPortDisable == nData1) {
2573                 CAMHAL_LOGDB("OMX_CommandPortDisable received for port %d", (int)nData2);
2574 
2575             } else if (OMX_CommandPortEnable == nData1) {
2576                 CAMHAL_LOGDB("OMX_CommandPortEnable received for port %d", (int)nData2);
2577 
2578             } else if (OMX_CommandMarkBuffer == nData1) {
2579                 ///This is not used currently
2580             }
2581 
2582             CAMHAL_LOGDA("-OMX_EventCmdComplete");
2583         break;
2584 
2585         case OMX_EventIndexSettingChanged:
2586             CAMHAL_LOGDB("OMX_EventIndexSettingChanged event received data1 0x%x, data2 0x%x",
2587                             ( unsigned int ) nData1, ( unsigned int ) nData2);
2588             break;
2589 
2590         case OMX_EventError:
2591             CAMHAL_LOGDB("OMX interface failed to execute OMX command %d", (int)nData1);
2592             CAMHAL_LOGDA("See OMX_INDEXTYPE for reference");
2593             if ( NULL != mErrorNotifier && ( ( OMX_U32 ) OMX_ErrorHardware == nData1 ) && mComponentState != OMX_StateInvalid)
2594               {
2595                 CAMHAL_LOGEA("***Got Fatal Error Notification***\n");
2596                 mComponentState = OMX_StateInvalid;
2597                 /*
2598                 Remove any unhandled events and
2599                 unblock any waiting semaphores
2600                 */
2601                 if ( !mEventSignalQ.isEmpty() )
2602                   {
2603                     for (unsigned int i = 0 ; i < mEventSignalQ.size(); i++ )
2604                       {
2605                         CAMHAL_LOGEB("***Removing %d EVENTS***** \n", mEventSignalQ.size());
2606                         //remove from queue and free msg
2607                         TIUTILS::Message *msg = mEventSignalQ.itemAt(i);
2608                         if ( NULL != msg )
2609                           {
2610                             Semaphore *sem  = (Semaphore*) msg->arg3;
2611                             mEventSignalQ.removeAt(i);
2612                             if ( sem )
2613                               {
2614                                 sem->Signal();
2615                               }
2616                             free(msg);
2617                           }
2618                       }
2619                   }
2620                 ///Report Error to App
2621                 mErrorNotifier->errorNotify(CAMERA_ERROR_FATAL);
2622               }
2623             break;
2624 
2625         case OMX_EventMark:
2626         break;
2627 
2628         case OMX_EventPortSettingsChanged:
2629         break;
2630 
2631         case OMX_EventBufferFlag:
2632         break;
2633 
2634         case OMX_EventResourcesAcquired:
2635         break;
2636 
2637         case OMX_EventComponentResumed:
2638         break;
2639 
2640         case OMX_EventDynamicResourcesAvailable:
2641         break;
2642 
2643         case OMX_EventPortFormatDetected:
2644         break;
2645 
2646         default:
2647         break;
2648     }
2649 
2650     ///Signal to the thread(s) waiting that the event has occured
2651     SignalEvent(hComponent, eEvent, nData1, nData2, pEventData);
2652 
2653    LOG_FUNCTION_NAME_EXIT;
2654    return eError;
2655 
2656     EXIT:
2657 
2658     CAMHAL_LOGEB("Exiting function %s because of eError=%x", __FUNCTION__, eError);
2659     LOG_FUNCTION_NAME_EXIT;
2660     return eError;
2661 }
2662 
SignalEvent(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_EVENTTYPE eEvent,OMX_IN OMX_U32 nData1,OMX_IN OMX_U32 nData2,OMX_IN OMX_PTR pEventData)2663 OMX_ERRORTYPE OMXCameraAdapter::SignalEvent(OMX_IN OMX_HANDLETYPE hComponent,
2664                                           OMX_IN OMX_EVENTTYPE eEvent,
2665                                           OMX_IN OMX_U32 nData1,
2666                                           OMX_IN OMX_U32 nData2,
2667                                           OMX_IN OMX_PTR pEventData)
2668 {
2669     Mutex::Autolock lock(mEventLock);
2670     TIUTILS::Message *msg;
2671 
2672     LOG_FUNCTION_NAME;
2673 
2674     if ( !mEventSignalQ.isEmpty() )
2675         {
2676         CAMHAL_LOGDA("Event queue not empty");
2677 
2678         for ( unsigned int i = 0 ; i < mEventSignalQ.size() ; i++ )
2679             {
2680             msg = mEventSignalQ.itemAt(i);
2681             if ( NULL != msg )
2682                 {
2683                 if( ( msg->command != 0 || msg->command == ( unsigned int ) ( eEvent ) )
2684                     && ( !msg->arg1 || ( OMX_U32 ) msg->arg1 == nData1 )
2685                     && ( !msg->arg2 || ( OMX_U32 ) msg->arg2 == nData2 )
2686                     && msg->arg3)
2687                     {
2688                     Semaphore *sem  = (Semaphore*) msg->arg3;
2689                     CAMHAL_LOGDA("Event matched, signalling sem");
2690                     mEventSignalQ.removeAt(i);
2691                     //Signal the semaphore provided
2692                     sem->Signal();
2693                     free(msg);
2694                     break;
2695                     }
2696                 }
2697             }
2698         }
2699     else
2700         {
2701         CAMHAL_LOGEA("Event queue empty!!!");
2702         }
2703 
2704     LOG_FUNCTION_NAME_EXIT;
2705 
2706     return OMX_ErrorNone;
2707 }
2708 
RemoveEvent(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_EVENTTYPE eEvent,OMX_IN OMX_U32 nData1,OMX_IN OMX_U32 nData2,OMX_IN OMX_PTR pEventData)2709 OMX_ERRORTYPE OMXCameraAdapter::RemoveEvent(OMX_IN OMX_HANDLETYPE hComponent,
2710                                             OMX_IN OMX_EVENTTYPE eEvent,
2711                                             OMX_IN OMX_U32 nData1,
2712                                             OMX_IN OMX_U32 nData2,
2713                                             OMX_IN OMX_PTR pEventData)
2714 {
2715   Mutex::Autolock lock(mEventLock);
2716   TIUTILS::Message *msg;
2717   LOG_FUNCTION_NAME;
2718 
2719   if ( !mEventSignalQ.isEmpty() )
2720     {
2721       CAMHAL_LOGDA("Event queue not empty");
2722 
2723       for ( unsigned int i = 0 ; i < mEventSignalQ.size() ; i++ )
2724         {
2725           msg = mEventSignalQ.itemAt(i);
2726           if ( NULL != msg )
2727             {
2728               if( ( msg->command != 0 || msg->command == ( unsigned int ) ( eEvent ) )
2729                   && ( !msg->arg1 || ( OMX_U32 ) msg->arg1 == nData1 )
2730                   && ( !msg->arg2 || ( OMX_U32 ) msg->arg2 == nData2 )
2731                   && msg->arg3)
2732                 {
2733                   Semaphore *sem  = (Semaphore*) msg->arg3;
2734                   CAMHAL_LOGDA("Event matched, signalling sem");
2735                   mEventSignalQ.removeAt(i);
2736                   free(msg);
2737                   break;
2738                 }
2739             }
2740         }
2741     }
2742   else
2743     {
2744       CAMHAL_LOGEA("Event queue empty!!!");
2745     }
2746   LOG_FUNCTION_NAME_EXIT;
2747 
2748   return OMX_ErrorNone;
2749 }
2750 
2751 
RegisterForEvent(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_EVENTTYPE eEvent,OMX_IN OMX_U32 nData1,OMX_IN OMX_U32 nData2,OMX_IN Semaphore & semaphore)2752 status_t OMXCameraAdapter::RegisterForEvent(OMX_IN OMX_HANDLETYPE hComponent,
2753                                           OMX_IN OMX_EVENTTYPE eEvent,
2754                                           OMX_IN OMX_U32 nData1,
2755                                           OMX_IN OMX_U32 nData2,
2756                                           OMX_IN Semaphore &semaphore)
2757 {
2758     status_t ret = NO_ERROR;
2759     ssize_t res;
2760     Mutex::Autolock lock(mEventLock);
2761 
2762     LOG_FUNCTION_NAME;
2763     TIUTILS::Message * msg = ( struct TIUTILS::Message * ) malloc(sizeof(struct TIUTILS::Message));
2764     if ( NULL != msg )
2765         {
2766         msg->command = ( unsigned int ) eEvent;
2767         msg->arg1 = ( void * ) nData1;
2768         msg->arg2 = ( void * ) nData2;
2769         msg->arg3 = ( void * ) &semaphore;
2770         msg->arg4 =  ( void * ) hComponent;
2771         res = mEventSignalQ.add(msg);
2772         if ( NO_MEMORY == res )
2773             {
2774             CAMHAL_LOGEA("No ressources for inserting OMX events");
2775             free(msg);
2776             ret = -ENOMEM;
2777             }
2778         }
2779 
2780     LOG_FUNCTION_NAME_EXIT;
2781 
2782     return ret;
2783 }
2784 
2785 /*========================================================*/
2786 /* @ fn SampleTest_EmptyBufferDone :: Application callback*/
2787 /*========================================================*/
OMXCameraAdapterEmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_PTR pAppData,OMX_IN OMX_BUFFERHEADERTYPE * pBuffHeader)2788 OMX_ERRORTYPE OMXCameraAdapterEmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
2789                                    OMX_IN OMX_PTR pAppData,
2790                                    OMX_IN OMX_BUFFERHEADERTYPE* pBuffHeader)
2791 {
2792     LOG_FUNCTION_NAME;
2793 
2794     OMX_ERRORTYPE eError = OMX_ErrorNone;
2795 
2796     OMXCameraAdapter *oca = (OMXCameraAdapter*)pAppData;
2797     eError = oca->OMXCameraAdapterEmptyBufferDone(hComponent, pBuffHeader);
2798 
2799     LOG_FUNCTION_NAME_EXIT;
2800     return eError;
2801 }
2802 
2803 
2804 /*========================================================*/
2805 /* @ fn SampleTest_EmptyBufferDone :: Application callback*/
2806 /*========================================================*/
OMXCameraAdapterEmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_BUFFERHEADERTYPE * pBuffHeader)2807 OMX_ERRORTYPE OMXCameraAdapter::OMXCameraAdapterEmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
2808                                    OMX_IN OMX_BUFFERHEADERTYPE* pBuffHeader)
2809 {
2810 
2811    LOG_FUNCTION_NAME;
2812 
2813    LOG_FUNCTION_NAME_EXIT;
2814 
2815    return OMX_ErrorNone;
2816 }
2817 
debugShowFPS()2818 static void debugShowFPS()
2819 {
2820     static int mFrameCount = 0;
2821     static int mLastFrameCount = 0;
2822     static nsecs_t mLastFpsTime = 0;
2823     static float mFps = 0;
2824     mFrameCount++;
2825     if (!(mFrameCount & 0x1F)) {
2826         nsecs_t now = systemTime();
2827         nsecs_t diff = now - mLastFpsTime;
2828         mFps = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
2829         mLastFpsTime = now;
2830         mLastFrameCount = mFrameCount;
2831         LOGD("Camera %d Frames, %f FPS", mFrameCount, mFps);
2832     }
2833     // XXX: mFPS has the value we want
2834 }
2835 
2836 /*========================================================*/
2837 /* @ fn SampleTest_FillBufferDone ::  Application callback*/
2838 /*========================================================*/
OMXCameraAdapterFillBufferDone(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_PTR pAppData,OMX_IN OMX_BUFFERHEADERTYPE * pBuffHeader)2839 OMX_ERRORTYPE OMXCameraAdapterFillBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
2840                                    OMX_IN OMX_PTR pAppData,
2841                                    OMX_IN OMX_BUFFERHEADERTYPE* pBuffHeader)
2842 {
2843     TIUTILS::Message msg;
2844     OMX_ERRORTYPE eError = OMX_ErrorNone;
2845 
2846     if (UNLIKELY(mDebugFps)) {
2847         debugShowFPS();
2848     }
2849 
2850     OMXCameraAdapter *adapter =  ( OMXCameraAdapter * ) pAppData;
2851     if ( NULL != adapter )
2852         {
2853         msg.command = OMXCameraAdapter::OMXCallbackHandler::CAMERA_FILL_BUFFER_DONE;
2854         msg.arg1 = ( void * ) hComponent;
2855         msg.arg2 = ( void * ) pBuffHeader;
2856         adapter->mOMXCallbackHandler->put(&msg);
2857         }
2858 
2859     return eError;
2860 }
2861 
2862 /*========================================================*/
2863 /* @ fn SampleTest_FillBufferDone ::  Application callback*/
2864 /*========================================================*/
OMXCameraAdapterFillBufferDone(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_BUFFERHEADERTYPE * pBuffHeader)2865 OMX_ERRORTYPE OMXCameraAdapter::OMXCameraAdapterFillBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
2866                                    OMX_IN OMX_BUFFERHEADERTYPE* pBuffHeader)
2867 {
2868 
2869     status_t  stat = NO_ERROR;
2870     status_t  res1, res2;
2871     OMXCameraPortParameters  *pPortParam;
2872     OMX_ERRORTYPE eError = OMX_ErrorNone;
2873     CameraFrame::FrameType typeOfFrame = CameraFrame::ALL_FRAMES;
2874     unsigned int refCount = 0;
2875     BaseCameraAdapter::AdapterState state, nextState;
2876     BaseCameraAdapter::getState(state);
2877     BaseCameraAdapter::getNextState(nextState);
2878     sp<CameraFDResult> fdResult = NULL;
2879     unsigned int mask = 0xFFFF;
2880     CameraFrame cameraFrame;
2881 
2882     res1 = res2 = NO_ERROR;
2883     pPortParam = &(mCameraAdapterParameters.mCameraPortParams[pBuffHeader->nOutputPortIndex]);
2884 
2885     if ( !pBuffHeader || !pBuffHeader->pBuffer ) {
2886         CAMHAL_LOGEA("NULL Buffer from OMX");
2887         return OMX_ErrorNone;
2888     }
2889 
2890     if (pBuffHeader->nOutputPortIndex == OMX_CAMERA_PORT_VIDEO_OUT_PREVIEW)
2891         {
2892 
2893         if ( ( PREVIEW_ACTIVE & state ) != PREVIEW_ACTIVE )
2894             {
2895             return OMX_ErrorNone;
2896             }
2897 
2898         recalculateFPS();
2899 
2900             {
2901             Mutex::Autolock lock(mFaceDetectionLock);
2902             if ( mFaceDetectionRunning && !mFaceDetectionPaused ) {
2903                 detectFaces(pBuffHeader, fdResult, pPortParam->mWidth, pPortParam->mHeight);
2904                 if ( NULL != fdResult.get() ) {
2905                     notifyFaceSubscribers(fdResult);
2906                     fdResult.clear();
2907                 }
2908             }
2909             }
2910 
2911         if ( (nextState & CAPTURE_ACTIVE) )
2912             {
2913             mPending3Asettings |= SetFocus;
2914             }
2915 
2916         ///Prepare the frames to be sent - initialize CameraFrame object and reference count
2917         if( mWaitingForSnapshot &&  (mCapturedFrames > 0) )
2918             {
2919             typeOfFrame = CameraFrame::SNAPSHOT_FRAME;
2920             mask = (unsigned int)CameraFrame::SNAPSHOT_FRAME;
2921             }
2922         else
2923             {
2924               typeOfFrame = CameraFrame::PREVIEW_FRAME_SYNC;
2925               mask = (unsigned int)CameraFrame::PREVIEW_FRAME_SYNC;
2926             }
2927 
2928         if (mRecording)
2929             {
2930             mask |= (unsigned int)CameraFrame::VIDEO_FRAME_SYNC;
2931             mFramesWithEncoder++;
2932             }
2933 
2934         //LOGV("FBD pBuffer = 0x%x", pBuffHeader->pBuffer);
2935 
2936         if( mWaitingForSnapshot )
2937           {
2938             mSnapshotCount++;
2939 
2940             if ( (mSnapshotCount == 1) &&
2941                  ((HIGH_SPEED == mCapMode) || (VIDEO_MODE == mCapMode)) )
2942               {
2943                 notifyShutterSubscribers();
2944               }
2945           }
2946 
2947         stat = sendCallBacks(cameraFrame, pBuffHeader, mask, pPortParam);
2948         mFramesWithDisplay++;
2949 
2950         mFramesWithDucati--;
2951 
2952 #ifdef DEBUG_LOG
2953         if(mBuffersWithDucati.indexOfKey((int)pBuffHeader->pBuffer)<0)
2954             {
2955             LOGE("Buffer was never with Ducati!! 0x%x", pBuffHeader->pBuffer);
2956             for(int i=0;i<mBuffersWithDucati.size();i++) LOGE("0x%x", mBuffersWithDucati.keyAt(i));
2957             }
2958         mBuffersWithDucati.removeItem((int)pBuffHeader->pBuffer);
2959 #endif
2960 
2961         if(mDebugFcs)
2962             CAMHAL_LOGEB("C[%d] D[%d] E[%d]", mFramesWithDucati, mFramesWithDisplay, mFramesWithEncoder);
2963 
2964         stat |= advanceZoom();
2965 
2966         // On the fly update to 3A settings not working
2967         // Do not update 3A here if we are in the middle of a capture
2968         // or in the middle of transitioning to it
2969         if( mPending3Asettings && ((nextState & CAPTURE_ACTIVE) == 0))
2970             {
2971             apply3Asettings(mParameters3A);
2972             }
2973         }
2974     else if( pBuffHeader->nOutputPortIndex == OMX_CAMERA_PORT_VIDEO_OUT_MEASUREMENT )
2975         {
2976         typeOfFrame = CameraFrame::FRAME_DATA_SYNC;
2977         mask = (unsigned int)CameraFrame::FRAME_DATA_SYNC;
2978 
2979         stat = sendCallBacks(cameraFrame, pBuffHeader, mask, pPortParam);
2980        }
2981     else if( pBuffHeader->nOutputPortIndex == OMX_CAMERA_PORT_IMAGE_OUT_IMAGE )
2982         {
2983         OMX_COLOR_FORMATTYPE pixFormat;
2984         const char *valstr = NULL;
2985 
2986         pixFormat = mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex].mColorFormat;
2987         valstr = mParams.getPictureFormat();
2988 
2989         if ( OMX_COLOR_FormatUnused == pixFormat )
2990             {
2991             typeOfFrame = CameraFrame::IMAGE_FRAME;
2992             mask = (unsigned int) CameraFrame::IMAGE_FRAME;
2993             }
2994         else if ( pixFormat == OMX_COLOR_FormatCbYCrY &&
2995                   ((valstr && !strcmp(valstr, CameraParameters::PIXEL_FORMAT_JPEG)) ||
2996                    !valstr) )
2997             {
2998             // signals to callbacks that this needs to be coverted to jpeg
2999             // before returning to framework
3000             typeOfFrame = CameraFrame::IMAGE_FRAME;
3001             mask = (unsigned int) CameraFrame::IMAGE_FRAME;
3002             cameraFrame.mQuirks |= CameraFrame::ENCODE_RAW_YUV422I_TO_JPEG;
3003 
3004             // populate exif data and pass to subscribers via quirk
3005             // subscriber is in charge of freeing exif data
3006             ExifElementsTable* exif = new ExifElementsTable();
3007             setupEXIF_libjpeg(exif);
3008             cameraFrame.mQuirks |= CameraFrame::HAS_EXIF_DATA;
3009             cameraFrame.mCookie2 = (void*) exif;
3010             }
3011         else
3012           {
3013             typeOfFrame = CameraFrame::RAW_FRAME;
3014             mask = (unsigned int) CameraFrame::RAW_FRAME;
3015           }
3016 
3017             pPortParam->mImageType = typeOfFrame;
3018 
3019             if((mCapturedFrames>0) && !mCaptureSignalled)
3020                 {
3021                 mCaptureSignalled = true;
3022                 mCaptureSem.Signal();
3023                 }
3024 
3025             if( ( CAPTURE_ACTIVE & state ) != CAPTURE_ACTIVE )
3026                 {
3027                 goto EXIT;
3028                 }
3029 
3030             {
3031             Mutex::Autolock lock(mBracketingLock);
3032             if ( mBracketingEnabled )
3033                 {
3034                 doBracketing(pBuffHeader, typeOfFrame);
3035                 return eError;
3036                 }
3037             }
3038 
3039         if ( 1 > mCapturedFrames )
3040             {
3041             goto EXIT;
3042             }
3043 
3044         CAMHAL_LOGDB("Captured Frames: %d", mCapturedFrames);
3045 
3046         mCapturedFrames--;
3047 
3048         stat = sendCallBacks(cameraFrame, pBuffHeader, mask, pPortParam);
3049 
3050         }
3051     else
3052         {
3053         CAMHAL_LOGEA("Frame received for non-(preview/capture/measure) port. This is yet to be supported");
3054         goto EXIT;
3055         }
3056 
3057     if ( NO_ERROR != stat )
3058         {
3059         CAMHAL_LOGDB("sendFrameToSubscribers error: %d", stat);
3060         returnFrame(pBuffHeader->pBuffer, typeOfFrame);
3061         }
3062 
3063     return eError;
3064 
3065     EXIT:
3066 
3067     CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, stat, eError);
3068 
3069     if ( NO_ERROR != stat )
3070         {
3071         if ( NULL != mErrorNotifier )
3072             {
3073             mErrorNotifier->errorNotify(CAMERA_ERROR_UNKNOWN);
3074             }
3075         }
3076 
3077     return eError;
3078 }
3079 
recalculateFPS()3080 status_t OMXCameraAdapter::recalculateFPS()
3081 {
3082     float currentFPS;
3083 
3084     {
3085         Mutex::Autolock lock(mFrameCountMutex);
3086         mFrameCount++;
3087         if (mFrameCount == 1) {
3088             mFirstFrameCondition.broadcast();
3089         }
3090     }
3091 
3092     if ( ( mFrameCount % FPS_PERIOD ) == 0 )
3093         {
3094         nsecs_t now = systemTime();
3095         nsecs_t diff = now - mLastFPSTime;
3096         currentFPS =  ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
3097         mLastFPSTime = now;
3098         mLastFrameCount = mFrameCount;
3099 
3100         if ( 1 == mIter )
3101             {
3102             mFPS = currentFPS;
3103             }
3104         else
3105             {
3106             //cumulative moving average
3107             mFPS = mLastFPS + (currentFPS - mLastFPS)/mIter;
3108             }
3109 
3110         mLastFPS = mFPS;
3111         mIter++;
3112         }
3113 
3114     return NO_ERROR;
3115 }
3116 
sendFrame(CameraFrame & frame)3117 status_t OMXCameraAdapter::sendFrame(CameraFrame &frame)
3118 {
3119     status_t ret = NO_ERROR;
3120 
3121     LOG_FUNCTION_NAME;
3122 
3123 
3124     if ( NO_ERROR == ret )
3125         {
3126         ret = sendFrameToSubscribers(&frame);
3127         }
3128 
3129     LOG_FUNCTION_NAME_EXIT;
3130 
3131     return ret;
3132 }
3133 
sendCallBacks(CameraFrame frame,OMX_IN OMX_BUFFERHEADERTYPE * pBuffHeader,unsigned int mask,OMXCameraPortParameters * port)3134 status_t OMXCameraAdapter::sendCallBacks(CameraFrame frame, OMX_IN OMX_BUFFERHEADERTYPE *pBuffHeader, unsigned int mask, OMXCameraPortParameters *port)
3135 {
3136   status_t ret = NO_ERROR;
3137 
3138   LOG_FUNCTION_NAME;
3139 
3140   if ( NULL == port)
3141     {
3142       CAMHAL_LOGEA("Invalid portParam");
3143       return -EINVAL;
3144     }
3145 
3146   if ( NULL == pBuffHeader )
3147     {
3148       CAMHAL_LOGEA("Invalid Buffer header");
3149       return -EINVAL;
3150     }
3151 
3152   Mutex::Autolock lock(mSubscriberLock);
3153 
3154   //frame.mFrameType = typeOfFrame;
3155   frame.mFrameMask = mask;
3156   frame.mBuffer = pBuffHeader->pBuffer;
3157   frame.mLength = pBuffHeader->nFilledLen;
3158   frame.mAlignment = port->mStride;
3159   frame.mOffset = pBuffHeader->nOffset;
3160   frame.mWidth = port->mWidth;
3161   frame.mHeight = port->mHeight;
3162   frame.mYuv[0] = NULL;
3163   frame.mYuv[1] = NULL;
3164 
3165   if ( onlyOnce && mRecording )
3166     {
3167       mTimeSourceDelta = (pBuffHeader->nTimeStamp * 1000) - systemTime(SYSTEM_TIME_MONOTONIC);
3168       onlyOnce = false;
3169     }
3170 
3171   frame.mTimestamp = (pBuffHeader->nTimeStamp * 1000) - mTimeSourceDelta;
3172 
3173   ret = setInitFrameRefCount(frame.mBuffer, mask);
3174 
3175   if (ret != NO_ERROR) {
3176      CAMHAL_LOGDB("Error in setInitFrameRefCount %d", ret);
3177   } else {
3178       ret = sendFrameToSubscribers(&frame);
3179   }
3180 
3181   CAMHAL_LOGVB("B 0x%x T %llu", frame.mBuffer, pBuffHeader->nTimeStamp);
3182 
3183   LOG_FUNCTION_NAME_EXIT;
3184 
3185   return ret;
3186 }
3187 
initCameraFrame(CameraFrame & frame,OMX_IN OMX_BUFFERHEADERTYPE * pBuffHeader,int typeOfFrame,OMXCameraPortParameters * port)3188 status_t OMXCameraAdapter::initCameraFrame( CameraFrame &frame,
3189                                             OMX_IN OMX_BUFFERHEADERTYPE *pBuffHeader,
3190                                             int typeOfFrame,
3191                                             OMXCameraPortParameters *port)
3192 {
3193     status_t ret = NO_ERROR;
3194 
3195     LOG_FUNCTION_NAME;
3196 
3197     if ( NULL == port)
3198         {
3199         CAMHAL_LOGEA("Invalid portParam");
3200         return -EINVAL;
3201         }
3202 
3203     if ( NULL == pBuffHeader )
3204         {
3205         CAMHAL_LOGEA("Invalid Buffer header");
3206         return -EINVAL;
3207         }
3208 
3209     frame.mFrameType = typeOfFrame;
3210     frame.mBuffer = pBuffHeader->pBuffer;
3211     frame.mLength = pBuffHeader->nFilledLen;
3212     frame.mAlignment = port->mStride;
3213     frame.mOffset = pBuffHeader->nOffset;
3214     frame.mWidth = port->mWidth;
3215     frame.mHeight = port->mHeight;
3216 
3217     // Timestamp in pBuffHeader->nTimeStamp is derived on DUCATI side, which is
3218     // is not  same time value as derived using systemTime. It would be ideal to use
3219     // exactly same time source across Android and Ducati, which is limited by
3220     // system now. So, workaround for now is to find the time offset between the two
3221     // time sources and compensate the difference, along with the latency involved
3222     // in camera buffer reaching CameraHal. Also, Do timeset offset calculation only
3223     // when recording is in progress, when nTimestamp will be populated by Camera
3224     if ( onlyOnce && mRecording )
3225         {
3226         mTimeSourceDelta = (pBuffHeader->nTimeStamp * 1000) - systemTime(SYSTEM_TIME_MONOTONIC);
3227         mTimeSourceDelta += kCameraBufferLatencyNs;
3228         onlyOnce = false;
3229         }
3230 
3231     // Calculating the new video timestamp based on offset from ducati source.
3232     frame.mTimestamp = (pBuffHeader->nTimeStamp * 1000) - mTimeSourceDelta;
3233 
3234         LOG_FUNCTION_NAME_EXIT;
3235 
3236     return ret;
3237 }
3238 
Handler()3239 bool OMXCameraAdapter::CommandHandler::Handler()
3240 {
3241     TIUTILS::Message msg;
3242     volatile int forever = 1;
3243     status_t stat;
3244     ErrorNotifier *errorNotify = NULL;
3245 
3246     LOG_FUNCTION_NAME;
3247 
3248     while ( forever )
3249         {
3250         stat = NO_ERROR;
3251         CAMHAL_LOGDA("Handler: waiting for messsage...");
3252         TIUTILS::MessageQueue::waitForMsg(&mCommandMsgQ, NULL, NULL, -1);
3253         mCommandMsgQ.get(&msg);
3254         CAMHAL_LOGDB("msg.command = %d", msg.command);
3255         switch ( msg.command ) {
3256             case CommandHandler::CAMERA_START_IMAGE_CAPTURE:
3257             {
3258                 stat = mCameraAdapter->startImageCapture();
3259                 break;
3260             }
3261             case CommandHandler::CAMERA_PERFORM_AUTOFOCUS:
3262             {
3263                 stat = mCameraAdapter->doAutoFocus();
3264                 break;
3265             }
3266             case CommandHandler::COMMAND_EXIT:
3267             {
3268                 CAMHAL_LOGEA("Exiting command handler");
3269                 forever = 0;
3270                 break;
3271             }
3272             case CommandHandler::CAMERA_SWITCH_TO_EXECUTING:
3273             {
3274               stat = mCameraAdapter->doSwitchToExecuting();
3275               break;
3276             }
3277         }
3278 
3279         if ( NO_ERROR != stat )
3280             {
3281             errorNotify = ( ErrorNotifier * ) msg.arg1;
3282             if ( NULL != errorNotify )
3283                 {
3284                 errorNotify->errorNotify(CAMERA_ERROR_HARD);
3285                 }
3286             }
3287         }
3288 
3289     LOG_FUNCTION_NAME_EXIT;
3290 
3291     return false;
3292 }
3293 
Handler()3294 bool OMXCameraAdapter::OMXCallbackHandler::Handler()
3295 {
3296     TIUTILS::Message msg;
3297     volatile int forever = 1;
3298     status_t ret = NO_ERROR;
3299 
3300     LOG_FUNCTION_NAME;
3301 
3302     while(forever){
3303         TIUTILS::MessageQueue::waitForMsg(&mCommandMsgQ, NULL, NULL, -1);
3304         mCommandMsgQ.get(&msg);
3305         switch ( msg.command ) {
3306             case OMXCallbackHandler::CAMERA_FILL_BUFFER_DONE:
3307             {
3308                 ret = mCameraAdapter->OMXCameraAdapterFillBufferDone(( OMX_HANDLETYPE ) msg.arg1,
3309                                                                      ( OMX_BUFFERHEADERTYPE *) msg.arg2);
3310                 break;
3311             }
3312             case CommandHandler::COMMAND_EXIT:
3313             {
3314                 CAMHAL_LOGEA("Exiting OMX callback handler");
3315                 forever = 0;
3316                 break;
3317             }
3318         }
3319     }
3320 
3321     LOG_FUNCTION_NAME_EXIT;
3322     return false;
3323 }
3324 
OMXCameraAdapter(size_t sensor_index)3325 OMXCameraAdapter::OMXCameraAdapter(size_t sensor_index): mComponentState (OMX_StateLoaded)
3326 {
3327     LOG_FUNCTION_NAME;
3328 
3329     mSensorIndex = sensor_index;
3330     mPictureRotation = 0;
3331     // Initial values
3332     mTimeSourceDelta = 0;
3333     onlyOnce = true;
3334 
3335     mDoAFSem.Create(0);
3336     mInitSem.Create(0);
3337     mFlushSem.Create(0);
3338     mUsePreviewDataSem.Create(0);
3339     mUsePreviewSem.Create(0);
3340     mUseCaptureSem.Create(0);
3341     mStartPreviewSem.Create(0);
3342     mStopPreviewSem.Create(0);
3343     mStartCaptureSem.Create(0);
3344     mStopCaptureSem.Create(0);
3345     mSwitchToLoadedSem.Create(0);
3346     mCaptureSem.Create(0);
3347 
3348     mSwitchToExecSem.Create(0);
3349 
3350     mCameraAdapterParameters.mHandleComp = 0;
3351 
3352     mUserSetExpLock = OMX_FALSE;
3353     mUserSetWbLock = OMX_FALSE;
3354 
3355     mFramesWithDucati = 0;
3356     mFramesWithDisplay = 0;
3357     mFramesWithEncoder = 0;
3358 
3359     LOG_FUNCTION_NAME_EXIT;
3360 }
3361 
~OMXCameraAdapter()3362 OMXCameraAdapter::~OMXCameraAdapter()
3363 {
3364     LOG_FUNCTION_NAME;
3365 
3366     Mutex::Autolock lock(gAdapterLock);
3367 
3368     //Return to OMX Loaded state
3369     switchToLoaded();
3370 
3371     ///De-init the OMX
3372     if( (mComponentState==OMX_StateLoaded) || (mComponentState==OMX_StateInvalid))
3373         {
3374         ///Free the handle for the Camera component
3375         if(mCameraAdapterParameters.mHandleComp)
3376             {
3377             OMX_FreeHandle(mCameraAdapterParameters.mHandleComp);
3378              mCameraAdapterParameters.mHandleComp = NULL;
3379             }
3380 
3381         OMX_Deinit();
3382         }
3383 
3384 
3385     //Remove any unhandled events
3386     if ( !mEventSignalQ.isEmpty() )
3387       {
3388         for (unsigned int i = 0 ; i < mEventSignalQ.size() ; i++ )
3389           {
3390             TIUTILS::Message *msg = mEventSignalQ.itemAt(i);
3391             //remove from queue and free msg
3392             if ( NULL != msg )
3393               {
3394                 Semaphore *sem  = (Semaphore*) msg->arg3;
3395                 mEventSignalQ.removeAt(i);
3396                 sem->Signal();
3397                 free(msg);
3398 
3399               }
3400           }
3401       }
3402 
3403     //Exit and free ref to command handling thread
3404     if ( NULL != mCommandHandler.get() )
3405     {
3406         TIUTILS::Message msg;
3407         msg.command = CommandHandler::COMMAND_EXIT;
3408         msg.arg1 = mErrorNotifier;
3409         mCommandHandler->put(&msg);
3410         mCommandHandler->requestExitAndWait();
3411         mCommandHandler.clear();
3412     }
3413 
3414     //Exit and free ref to callback handling thread
3415     if ( NULL != mOMXCallbackHandler.get() )
3416     {
3417         TIUTILS::Message msg;
3418         msg.command = OMXCallbackHandler::COMMAND_EXIT;
3419         mOMXCallbackHandler->put(&msg);
3420         mOMXCallbackHandler->requestExitAndWait();
3421         mOMXCallbackHandler.clear();
3422     }
3423 
3424     LOG_FUNCTION_NAME_EXIT;
3425 }
3426 
CameraAdapter_Factory(size_t sensor_index)3427 extern "C" CameraAdapter* CameraAdapter_Factory(size_t sensor_index)
3428 {
3429     CameraAdapter *adapter = NULL;
3430     Mutex::Autolock lock(gAdapterLock);
3431 
3432     LOG_FUNCTION_NAME;
3433 
3434     adapter = new OMXCameraAdapter(sensor_index);
3435     if ( adapter ) {
3436         CAMHAL_LOGDB("New OMX Camera adapter instance created for sensor %d",sensor_index);
3437     } else {
3438         CAMHAL_LOGEA("Camera adapter create failed!");
3439     }
3440 
3441     LOG_FUNCTION_NAME_EXIT;
3442 
3443     return adapter;
3444 }
3445 
OMXCameraGetHandle(OMX_HANDLETYPE * handle,OMX_PTR pAppData)3446 OMX_ERRORTYPE OMXCameraAdapter::OMXCameraGetHandle(OMX_HANDLETYPE *handle, OMX_PTR pAppData )
3447 {
3448     OMX_ERRORTYPE eError = OMX_ErrorUndefined;
3449 
3450     int retries = 5;
3451     while(eError!=OMX_ErrorNone && --retries>=0) {
3452 
3453       // Setup key parameters to send to Ducati during init
3454       OMX_CALLBACKTYPE oCallbacks;
3455 
3456       // Initialize the callback handles
3457       oCallbacks.EventHandler    = android::OMXCameraAdapterEventHandler;
3458       oCallbacks.EmptyBufferDone = android::OMXCameraAdapterEmptyBufferDone;
3459       oCallbacks.FillBufferDone  = android::OMXCameraAdapterFillBufferDone;
3460 
3461       // Get Handle
3462       eError = OMX_GetHandle(handle, (OMX_STRING)"OMX.TI.DUCATI1.VIDEO.CAMERA", pAppData, &oCallbacks);
3463       if (eError != OMX_ErrorNone) {
3464         CAMHAL_LOGEB("OMX_GetHandle -0x%x", eError);
3465         //Sleep for 100 mS
3466         usleep(100000);
3467       } else {
3468         break;
3469       }
3470     }
3471 
3472     return eError;
3473 }
3474 
CameraAdapter_Capabilities(CameraProperties::Properties * properties_array,const unsigned int starting_camera,const unsigned int max_camera)3475 extern "C" int CameraAdapter_Capabilities(CameraProperties::Properties* properties_array,
3476                                           const unsigned int starting_camera,
3477                                           const unsigned int max_camera) {
3478     int num_cameras_supported = 0;
3479     CameraProperties::Properties* properties = NULL;
3480     OMX_ERRORTYPE eError = OMX_ErrorNone;
3481     OMX_HANDLETYPE handle = NULL;
3482     OMX_TI_CAPTYPE caps;
3483 
3484     LOG_FUNCTION_NAME;
3485 
3486     Mutex::Autolock lock(gAdapterLock);
3487 
3488     if (!properties_array) {
3489         CAMHAL_LOGEB("invalid param: properties = 0x%p", properties_array);
3490         LOG_FUNCTION_NAME_EXIT;
3491         return -EINVAL;
3492     }
3493 
3494     eError = OMX_Init();
3495     if (eError != OMX_ErrorNone) {
3496       CAMHAL_LOGEB("Error OMX_Init -0x%x", eError);
3497       return eError;
3498     }
3499 
3500     eError = OMXCameraAdapter::OMXCameraGetHandle(&handle);
3501     if (eError != OMX_ErrorNone) {
3502         CAMHAL_LOGEB("OMX_GetHandle -0x%x", eError);
3503         goto EXIT;
3504     }
3505 
3506     // Continue selecting sensor and then querying OMX Camera for it's capabilities
3507     // When sensor select returns an error, we know to break and stop
3508     while (eError == OMX_ErrorNone &&
3509            (starting_camera + num_cameras_supported) < max_camera) {
3510         // sensor select
3511         OMX_CONFIG_SENSORSELECTTYPE sensorSelect;
3512         OMX_INIT_STRUCT_PTR (&sensorSelect, OMX_CONFIG_SENSORSELECTTYPE);
3513         sensorSelect.eSensor = (OMX_SENSORSELECT) num_cameras_supported;
3514         eError = OMX_SetConfig(handle, ( OMX_INDEXTYPE ) OMX_TI_IndexConfigSensorSelect, &sensorSelect);
3515 
3516         if ( OMX_ErrorNone != eError ) {
3517             break;
3518         }
3519 
3520         // get and fill capabilities
3521         properties = properties_array + starting_camera + num_cameras_supported;
3522         OMXCameraAdapter::getCaps(properties, handle);
3523 
3524         // need to fill facing information
3525         // assume that only sensor 0 is back facing
3526         if (num_cameras_supported == 0) {
3527             properties->set(CameraProperties::FACING_INDEX, TICameraParameters::FACING_BACK);
3528         } else {
3529             properties->set(CameraProperties::FACING_INDEX, TICameraParameters::FACING_FRONT);
3530         }
3531 
3532         num_cameras_supported++;
3533     }
3534 
3535  EXIT:
3536     // clean up
3537     if(handle) {
3538         OMX_FreeHandle(handle);
3539         handle=NULL;
3540     }
3541     OMX_Deinit();
3542 
3543     LOG_FUNCTION_NAME_EXIT;
3544 
3545     return num_cameras_supported;
3546 }
3547 
3548 };
3549 
3550 
3551 /*--------------------Camera Adapter Class ENDS here-----------------------------*/
3552 
3553