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