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