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