OMXCapture.cpp revision fc8ab094473901857ee382396eebc5d52ac4c6c6
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 OMXCapture.cpp
19*
20* This file contains functionality for handling image capture.
21*
22*/
23
24#undef LOG_TAG
25
26#define LOG_TAG "CameraHAL"
27
28#include "CameraHal.h"
29#include "OMXCameraAdapter.h"
30#include "ErrorUtils.h"
31
32
33namespace android {
34
35status_t OMXCameraAdapter::setParametersCapture(const CameraParameters &params,
36                                                BaseCameraAdapter::AdapterState state)
37{
38    status_t ret = NO_ERROR;
39    const char *str = NULL;
40    int w, h;
41    OMX_COLOR_FORMATTYPE pixFormat;
42    const char *valstr = NULL;
43
44    LOG_FUNCTION_NAME;
45
46    OMXCameraPortParameters *cap;
47    cap = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
48
49    params.getPictureSize(&w, &h);
50
51    if ( ( w != ( int ) cap->mWidth ) ||
52          ( h != ( int ) cap->mHeight ) )
53        {
54        mPendingCaptureSettings |= SetFormat;
55        }
56
57    cap->mWidth = w;
58    cap->mHeight = h;
59    //TODO: Support more pixelformats
60    cap->mStride = 2;
61
62    CAMHAL_LOGVB("Image: cap.mWidth = %d", (int)cap->mWidth);
63    CAMHAL_LOGVB("Image: cap.mHeight = %d", (int)cap->mHeight);
64
65    if ( (valstr = params.getPictureFormat()) != NULL )
66        {
67        if (strcmp(valstr, (const char *) CameraParameters::PIXEL_FORMAT_YUV422I) == 0)
68            {
69            CAMHAL_LOGDA("CbYCrY format selected");
70            pixFormat = OMX_COLOR_FormatCbYCrY;
71            }
72        else if(strcmp(valstr, (const char *) CameraParameters::PIXEL_FORMAT_YUV420SP) == 0)
73            {
74            CAMHAL_LOGDA("YUV420SP format selected");
75            pixFormat = OMX_COLOR_FormatYUV420SemiPlanar;
76            }
77        else if(strcmp(valstr, (const char *) CameraParameters::PIXEL_FORMAT_RGB565) == 0)
78            {
79            CAMHAL_LOGDA("RGB565 format selected");
80            pixFormat = OMX_COLOR_Format16bitRGB565;
81            }
82        else if(strcmp(valstr, (const char *) CameraParameters::PIXEL_FORMAT_JPEG) == 0)
83            {
84            CAMHAL_LOGDA("JPEG format selected");
85            pixFormat = OMX_COLOR_FormatUnused;
86            mCodingMode = CodingNone;
87            }
88        else if(strcmp(valstr, (const char *) TICameraParameters::PIXEL_FORMAT_JPS) == 0)
89            {
90            CAMHAL_LOGDA("JPS format selected");
91            pixFormat = OMX_COLOR_FormatUnused;
92            mCodingMode = CodingJPS;
93            }
94        else if(strcmp(valstr, (const char *) TICameraParameters::PIXEL_FORMAT_MPO) == 0)
95            {
96            CAMHAL_LOGDA("MPO format selected");
97            pixFormat = OMX_COLOR_FormatUnused;
98            mCodingMode = CodingMPO;
99            }
100        else if(strcmp(valstr, (const char *) TICameraParameters::PIXEL_FORMAT_RAW_JPEG) == 0)
101            {
102            CAMHAL_LOGDA("RAW + JPEG format selected");
103            pixFormat = OMX_COLOR_FormatUnused;
104            mCodingMode = CodingRAWJPEG;
105            }
106        else if(strcmp(valstr, (const char *) TICameraParameters::PIXEL_FORMAT_RAW_MPO) == 0)
107            {
108            CAMHAL_LOGDA("RAW + MPO format selected");
109            pixFormat = OMX_COLOR_FormatUnused;
110            mCodingMode = CodingRAWMPO;
111            }
112        else if(strcmp(valstr, (const char *) TICameraParameters::PIXEL_FORMAT_RAW) == 0)
113            {
114            CAMHAL_LOGDA("RAW Picture format selected");
115            pixFormat = OMX_COLOR_FormatRawBayer10bit;
116            }
117        else
118            {
119            CAMHAL_LOGEA("Invalid format, JPEG format selected as default");
120            pixFormat = OMX_COLOR_FormatUnused;
121            }
122        }
123    else
124        {
125        CAMHAL_LOGEA("Picture format is NULL, defaulting to JPEG");
126        pixFormat = OMX_COLOR_FormatUnused;
127        }
128
129    // JPEG capture is not supported in video mode by OMX Camera
130    // Set capture format to yuv422i...jpeg encode will
131    // be done on A9
132    valstr = params.get(TICameraParameters::KEY_CAP_MODE);
133    if ( (valstr && !strcmp(valstr, (const char *) TICameraParameters::VIDEO_MODE)) &&
134         (pixFormat == OMX_COLOR_FormatUnused) ) {
135        CAMHAL_LOGDA("Capturing in video mode...selecting yuv422i");
136        pixFormat = OMX_COLOR_FormatCbYCrY;
137    }
138
139    if ( pixFormat != cap->mColorFormat )
140        {
141        mPendingCaptureSettings |= SetFormat;
142        cap->mColorFormat = pixFormat;
143        }
144
145    str = params.get(TICameraParameters::KEY_EXP_BRACKETING_RANGE);
146    if ( NULL != str ) {
147        parseExpRange(str, mExposureBracketingValues, EXP_BRACKET_RANGE, mExposureBracketingValidEntries);
148    } else {
149        // if bracketing was previously set...we set again before capturing to clear
150        if (mExposureBracketingValidEntries) mPendingCaptureSettings |= SetExpBracket;
151        mExposureBracketingValidEntries = 0;
152    }
153
154    if ( params.getInt(CameraParameters::KEY_ROTATION) != -1 )
155        {
156        if (params.getInt(CameraParameters::KEY_ROTATION) != mPictureRotation) {
157            mPendingCaptureSettings |= SetRotation;
158        }
159        mPictureRotation = params.getInt(CameraParameters::KEY_ROTATION);
160        }
161    else
162        {
163        if (mPictureRotation) mPendingCaptureSettings |= SetRotation;
164        mPictureRotation = 0;
165        }
166
167    CAMHAL_LOGVB("Picture Rotation set %d", mPictureRotation);
168
169    // Read Sensor Orientation and set it based on perating mode
170
171     if (( params.getInt(TICameraParameters::KEY_SENSOR_ORIENTATION) != -1 ) && (mCapMode == OMXCameraAdapter::VIDEO_MODE))
172        {
173         mSensorOrientation = params.getInt(TICameraParameters::KEY_SENSOR_ORIENTATION);
174         if (mSensorOrientation == 270 ||mSensorOrientation==90)
175             {
176             CAMHAL_LOGEA(" Orientation is 270/90. So setting counter rotation  to Ducati");
177             mSensorOrientation +=180;
178             mSensorOrientation%=360;
179              }
180         }
181     else
182        {
183         mSensorOrientation = 0;
184        }
185
186     CAMHAL_LOGVB("Sensor Orientation  set : %d", mSensorOrientation);
187
188    if ( params.getInt(TICameraParameters::KEY_BURST)  >= 1 )
189        {
190        if (params.getInt(TICameraParameters::KEY_BURST) != mBurstFrames) {
191            mPendingCaptureSettings |= SetExpBracket;
192        }
193        mBurstFrames = params.getInt(TICameraParameters::KEY_BURST);
194        }
195    else
196        {
197        if (mBurstFrames != 1) mPendingCaptureSettings |= SetExpBracket;
198        mBurstFrames = 1;
199        }
200
201    CAMHAL_LOGVB("Burst Frames set %d", mBurstFrames);
202
203    if ( ( params.getInt(CameraParameters::KEY_JPEG_QUALITY)  >= MIN_JPEG_QUALITY ) &&
204         ( params.getInt(CameraParameters::KEY_JPEG_QUALITY)  <= MAX_JPEG_QUALITY ) )
205        {
206        if (params.getInt(CameraParameters::KEY_JPEG_QUALITY) != mPictureQuality) {
207            mPendingCaptureSettings |= SetQuality;
208        }
209        mPictureQuality = params.getInt(CameraParameters::KEY_JPEG_QUALITY);
210        }
211    else
212        {
213        if (mPictureQuality != MAX_JPEG_QUALITY) mPendingCaptureSettings |= SetQuality;
214        mPictureQuality = MAX_JPEG_QUALITY;
215        }
216
217    CAMHAL_LOGVB("Picture Quality set %d", mPictureQuality);
218
219    if ( params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH)  >= 0 )
220        {
221        if (params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH) != mThumbWidth) {
222            mPendingCaptureSettings |= SetThumb;
223        }
224        mThumbWidth = params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
225        }
226    else
227        {
228        if (mThumbWidth != DEFAULT_THUMB_WIDTH) mPendingCaptureSettings |= SetThumb;
229        mThumbWidth = DEFAULT_THUMB_WIDTH;
230        }
231
232
233    CAMHAL_LOGVB("Picture Thumb width set %d", mThumbWidth);
234
235    if ( params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT)  >= 0 )
236        {
237        if (params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT) != mThumbHeight) {
238            mPendingCaptureSettings |= SetThumb;
239        }
240        mThumbHeight = params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
241        }
242    else
243        {
244        if (mThumbHeight != DEFAULT_THUMB_HEIGHT) mPendingCaptureSettings |= SetThumb;
245        mThumbHeight = DEFAULT_THUMB_HEIGHT;
246        }
247
248
249    CAMHAL_LOGVB("Picture Thumb height set %d", mThumbHeight);
250
251    if ( ( params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY)  >= MIN_JPEG_QUALITY ) &&
252         ( params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY)  <= MAX_JPEG_QUALITY ) )
253        {
254        if (params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY) != mThumbQuality) {
255            mPendingCaptureSettings |= SetThumb;
256        }
257        mThumbQuality = params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
258        }
259    else
260        {
261        if (mThumbQuality != MAX_JPEG_QUALITY) mPendingCaptureSettings |= SetThumb;
262        mThumbQuality = MAX_JPEG_QUALITY;
263        }
264
265    CAMHAL_LOGDB("Thumbnail Quality set %d", mThumbQuality);
266
267    if (mFirstTimeInit) {
268        mPendingCaptureSettings = ECapturesettingsAll;
269    }
270
271    if (mPendingCaptureSettings) {
272        disableImagePort();
273        if ( NULL != mReleaseImageBuffersCallback ) {
274            mReleaseImageBuffersCallback(mReleaseData);
275        }
276    }
277
278    LOG_FUNCTION_NAME_EXIT;
279
280    return ret;
281}
282
283status_t OMXCameraAdapter::getPictureBufferSize(size_t &length, size_t bufferCount)
284{
285    status_t ret = NO_ERROR;
286    OMXCameraPortParameters *imgCaptureData = NULL;
287    OMX_ERRORTYPE eError = OMX_ErrorNone;
288
289    LOG_FUNCTION_NAME;
290
291    if ( NO_ERROR == ret )
292        {
293        imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
294
295        imgCaptureData->mNumBufs = bufferCount;
296
297        // check if image port is already configured...
298        // if it already configured then we don't have to query again
299        if (!mCaptureConfigured) {
300            ret = setFormat(OMX_CAMERA_PORT_IMAGE_OUT_IMAGE, *imgCaptureData);
301        }
302
303        if ( ret == NO_ERROR )
304            {
305            length = imgCaptureData->mBufSize;
306            }
307        else
308            {
309            CAMHAL_LOGEB("setFormat() failed 0x%x", ret);
310            length = 0;
311            }
312        }
313
314    CAMHAL_LOGDB("getPictureBufferSize %d", length);
315
316    LOG_FUNCTION_NAME_EXIT;
317
318    return ret;
319}
320
321status_t OMXCameraAdapter::parseExpRange(const char *rangeStr,
322                                         int * expRange,
323                                         size_t count,
324                                         size_t &validEntries)
325{
326    status_t ret = NO_ERROR;
327    char *ctx, *expVal;
328    char *tmp = NULL;
329    size_t i = 0;
330
331    LOG_FUNCTION_NAME;
332
333    if ( NULL == rangeStr )
334        {
335        return -EINVAL;
336        }
337
338    if ( NULL == expRange )
339        {
340        return -EINVAL;
341        }
342
343    if ( NO_ERROR == ret )
344        {
345        tmp = ( char * ) malloc( strlen(rangeStr) + 1 );
346
347        if ( NULL == tmp )
348            {
349            CAMHAL_LOGEA("No resources for temporary buffer");
350            return -1;
351            }
352        memset(tmp, '\0', strlen(rangeStr) + 1);
353
354        }
355
356    if ( NO_ERROR == ret )
357        {
358        strncpy(tmp, rangeStr, strlen(rangeStr) );
359        expVal = strtok_r( (char *) tmp, CameraHal::PARAMS_DELIMITER, &ctx);
360
361        i = 0;
362        while ( ( NULL != expVal ) && ( i < count ) )
363            {
364            expRange[i] = atoi(expVal);
365            expVal = strtok_r(NULL, CameraHal::PARAMS_DELIMITER, &ctx);
366            i++;
367            }
368        validEntries = i;
369        }
370
371    if ( NULL != tmp )
372        {
373        free(tmp);
374        }
375
376    LOG_FUNCTION_NAME_EXIT;
377
378    return ret;
379}
380
381status_t OMXCameraAdapter::setExposureBracketing(int *evValues,
382                                                 size_t evCount,
383                                                 size_t frameCount)
384{
385    status_t ret = NO_ERROR;
386    OMX_ERRORTYPE eError = OMX_ErrorNone;
387    OMX_CONFIG_CAPTUREMODETYPE expCapMode;
388    OMX_CONFIG_EXTCAPTUREMODETYPE extExpCapMode;
389
390    LOG_FUNCTION_NAME;
391
392    if ( OMX_StateInvalid == mComponentState )
393        {
394        CAMHAL_LOGEA("OMX component is in invalid state");
395        ret = -EINVAL;
396        }
397
398    if ( NULL == evValues )
399        {
400        CAMHAL_LOGEA("Exposure compensation values pointer is invalid");
401        ret = -EINVAL;
402        }
403
404    if ( NO_ERROR == ret )
405        {
406        OMX_INIT_STRUCT_PTR (&expCapMode, OMX_CONFIG_CAPTUREMODETYPE);
407        expCapMode.nPortIndex = mCameraAdapterParameters.mImagePortIndex;
408
409        /// If frameCount>0 but evCount<=0, then this is the case of HQ burst.
410        //Otherwise, it is normal HQ capture
411        ///If frameCount>0 and evCount>0 then this is the cause of HQ Exposure bracketing.
412        if ( 0 == evCount && 0 == frameCount )
413            {
414            expCapMode.bFrameLimited = OMX_FALSE;
415            }
416        else
417            {
418            expCapMode.bFrameLimited = OMX_TRUE;
419            expCapMode.nFrameLimit = frameCount;
420            }
421
422        eError =  OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
423                                OMX_IndexConfigCaptureMode,
424                                &expCapMode);
425        if ( OMX_ErrorNone != eError )
426            {
427            CAMHAL_LOGEB("Error while configuring capture mode 0x%x", eError);
428            }
429        else
430            {
431            CAMHAL_LOGDA("Camera capture mode configured successfully");
432            }
433        }
434
435    if ( NO_ERROR == ret )
436        {
437        OMX_INIT_STRUCT_PTR (&extExpCapMode, OMX_CONFIG_EXTCAPTUREMODETYPE);
438        extExpCapMode.nPortIndex = mCameraAdapterParameters.mImagePortIndex;
439
440        if ( 0 == evCount )
441            {
442            extExpCapMode.bEnableBracketing = OMX_FALSE;
443            }
444        else
445            {
446            extExpCapMode.bEnableBracketing = OMX_TRUE;
447            extExpCapMode.tBracketConfigType.eBracketMode = OMX_BracketExposureRelativeInEV;
448            extExpCapMode.tBracketConfigType.nNbrBracketingValues = evCount - 1;
449            }
450
451        for ( unsigned int i = 0 ; i < evCount ; i++ )
452            {
453            extExpCapMode.tBracketConfigType.nBracketValues[i]  =  ( evValues[i] * ( 1 << Q16_OFFSET ) )  / 10;
454            }
455
456        eError =  OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
457                                ( OMX_INDEXTYPE ) OMX_IndexConfigExtCaptureMode,
458                                &extExpCapMode);
459        if ( OMX_ErrorNone != eError )
460            {
461            CAMHAL_LOGEB("Error while configuring extended capture mode 0x%x", eError);
462            }
463        else
464            {
465            CAMHAL_LOGDA("Extended camera capture mode configured successfully");
466            }
467        }
468
469    LOG_FUNCTION_NAME_EXIT;
470
471    return ret;
472}
473
474status_t OMXCameraAdapter::setShutterCallback(bool enabled)
475{
476    status_t ret = NO_ERROR;
477    OMX_ERRORTYPE eError = OMX_ErrorNone;
478    OMX_CONFIG_CALLBACKREQUESTTYPE shutterRequstCallback;
479
480    LOG_FUNCTION_NAME;
481
482    if ( OMX_StateExecuting != mComponentState )
483        {
484        CAMHAL_LOGEA("OMX component not in executing state");
485        ret = -1;
486        }
487
488    if ( NO_ERROR == ret )
489        {
490
491        OMX_INIT_STRUCT_PTR (&shutterRequstCallback, OMX_CONFIG_CALLBACKREQUESTTYPE);
492        shutterRequstCallback.nPortIndex = OMX_ALL;
493
494        if ( enabled )
495            {
496            shutterRequstCallback.bEnable = OMX_TRUE;
497            shutterRequstCallback.nIndex = ( OMX_INDEXTYPE ) OMX_TI_IndexConfigShutterCallback;
498            CAMHAL_LOGDA("Enabling shutter callback");
499            }
500        else
501            {
502            shutterRequstCallback.bEnable = OMX_FALSE;
503            shutterRequstCallback.nIndex = ( OMX_INDEXTYPE ) OMX_TI_IndexConfigShutterCallback;
504            CAMHAL_LOGDA("Disabling shutter callback");
505            }
506
507        eError =  OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
508                                ( OMX_INDEXTYPE ) OMX_IndexConfigCallbackRequest,
509                                &shutterRequstCallback);
510        if ( OMX_ErrorNone != eError )
511            {
512            CAMHAL_LOGEB("Error registering shutter callback 0x%x", eError);
513            ret = -1;
514            }
515        else
516            {
517            CAMHAL_LOGDB("Shutter callback for index 0x%x registered successfully",
518                         OMX_TI_IndexConfigShutterCallback);
519            }
520        }
521
522    LOG_FUNCTION_NAME_EXIT;
523
524    return ret;
525}
526
527status_t OMXCameraAdapter::doBracketing(OMX_BUFFERHEADERTYPE *pBuffHeader,
528                                        CameraFrame::FrameType typeOfFrame)
529{
530    status_t ret = NO_ERROR;
531    int currentBufferIdx, nextBufferIdx;
532    OMXCameraPortParameters * imgCaptureData = NULL;
533
534    LOG_FUNCTION_NAME;
535
536    imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
537
538    if ( OMX_StateExecuting != mComponentState )
539        {
540        CAMHAL_LOGEA("OMX component is not in executing state");
541        ret = -EINVAL;
542        }
543
544    if ( NO_ERROR == ret )
545        {
546        currentBufferIdx = ( unsigned int ) pBuffHeader->pAppPrivate;
547
548        if ( currentBufferIdx >= imgCaptureData->mNumBufs)
549            {
550            CAMHAL_LOGEB("Invalid bracketing buffer index 0x%x", currentBufferIdx);
551            ret = -EINVAL;
552            }
553        }
554
555    if ( NO_ERROR == ret )
556        {
557        mBracketingBuffersQueued[currentBufferIdx] = false;
558        mBracketingBuffersQueuedCount--;
559
560        if ( 0 >= mBracketingBuffersQueuedCount )
561            {
562            nextBufferIdx = ( currentBufferIdx + 1 ) % imgCaptureData->mNumBufs;
563            mBracketingBuffersQueued[nextBufferIdx] = true;
564            mBracketingBuffersQueuedCount++;
565            mLastBracetingBufferIdx = nextBufferIdx;
566            setFrameRefCount(imgCaptureData->mBufferHeader[nextBufferIdx]->pBuffer, typeOfFrame, 1);
567            returnFrame(imgCaptureData->mBufferHeader[nextBufferIdx]->pBuffer, typeOfFrame);
568            }
569        }
570
571    LOG_FUNCTION_NAME_EXIT;
572
573    return ret;
574}
575
576status_t OMXCameraAdapter::sendBracketFrames()
577{
578    status_t ret = NO_ERROR;
579    int currentBufferIdx;
580    OMXCameraPortParameters * imgCaptureData = NULL;
581
582    LOG_FUNCTION_NAME;
583
584    imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
585
586    if ( OMX_StateExecuting != mComponentState )
587        {
588        CAMHAL_LOGEA("OMX component is not in executing state");
589        ret = -EINVAL;
590        }
591
592    if ( NO_ERROR == ret )
593        {
594
595        currentBufferIdx = mLastBracetingBufferIdx;
596        do
597            {
598            currentBufferIdx++;
599            currentBufferIdx %= imgCaptureData->mNumBufs;
600            if (!mBracketingBuffersQueued[currentBufferIdx] )
601                {
602                CameraFrame cameraFrame;
603                sendCallBacks(cameraFrame,
604                              imgCaptureData->mBufferHeader[currentBufferIdx],
605                              imgCaptureData->mImageType,
606                              imgCaptureData);
607                }
608            } while ( currentBufferIdx != mLastBracetingBufferIdx );
609
610        }
611
612    LOG_FUNCTION_NAME_EXIT;
613
614    return ret;
615}
616
617status_t OMXCameraAdapter::startBracketing(int range)
618{
619    status_t ret = NO_ERROR;
620    OMXCameraPortParameters * imgCaptureData = NULL;
621
622    LOG_FUNCTION_NAME;
623
624    imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
625
626    if ( OMX_StateExecuting != mComponentState )
627        {
628        CAMHAL_LOGEA("OMX component is not in executing state");
629        ret = -EINVAL;
630        }
631
632        {
633        Mutex::Autolock lock(mBracketingLock);
634
635        if ( mBracketingEnabled )
636            {
637            return ret;
638            }
639        }
640
641    if ( 0 == imgCaptureData->mNumBufs )
642        {
643        CAMHAL_LOGEB("Image capture buffers set to %d", imgCaptureData->mNumBufs);
644        ret = -EINVAL;
645        }
646
647    if ( mPending3Asettings )
648        apply3Asettings(mParameters3A);
649
650    if ( NO_ERROR == ret )
651        {
652        Mutex::Autolock lock(mBracketingLock);
653
654        mBracketingRange = range;
655        mBracketingBuffersQueued = new bool[imgCaptureData->mNumBufs];
656        if ( NULL == mBracketingBuffersQueued )
657            {
658            CAMHAL_LOGEA("Unable to allocate bracketing management structures");
659            ret = -1;
660            }
661
662        if ( NO_ERROR == ret )
663            {
664            mBracketingBuffersQueuedCount = imgCaptureData->mNumBufs;
665            mLastBracetingBufferIdx = mBracketingBuffersQueuedCount - 1;
666
667            for ( int i = 0 ; i  < imgCaptureData->mNumBufs ; i++ )
668                {
669                mBracketingBuffersQueued[i] = true;
670                }
671
672            }
673        }
674
675    if ( NO_ERROR == ret )
676        {
677
678        ret = startImageCapture();
679            {
680            Mutex::Autolock lock(mBracketingLock);
681
682            if ( NO_ERROR == ret )
683                {
684                mBracketingEnabled = true;
685                }
686            else
687                {
688                mBracketingEnabled = false;
689                }
690            }
691        }
692
693    LOG_FUNCTION_NAME_EXIT;
694
695    return ret;
696}
697
698status_t OMXCameraAdapter::stopBracketing()
699{
700  status_t ret = NO_ERROR;
701
702    LOG_FUNCTION_NAME;
703
704    Mutex::Autolock lock(mBracketingLock);
705
706    if ( NULL != mBracketingBuffersQueued )
707    {
708        delete [] mBracketingBuffersQueued;
709    }
710
711    ret = stopImageCapture();
712
713    mBracketingBuffersQueued = NULL;
714    mBracketingEnabled = false;
715    mBracketingBuffersQueuedCount = 0;
716    mLastBracetingBufferIdx = 0;
717
718    LOG_FUNCTION_NAME_EXIT;
719
720    return ret;
721}
722
723status_t OMXCameraAdapter::startImageCapture()
724{
725    status_t ret = NO_ERROR;
726    OMX_ERRORTYPE eError = OMX_ErrorNone;
727    OMXCameraPortParameters * capData = NULL;
728    OMX_CONFIG_BOOLEANTYPE bOMX;
729
730    LOG_FUNCTION_NAME;
731
732    if(!mCaptureConfigured)
733        {
734        ///Image capture was cancelled before we could start
735        return NO_ERROR;
736        }
737
738    if ( 0 != mStartCaptureSem.Count() )
739        {
740        CAMHAL_LOGEB("Error mStartCaptureSem semaphore count %d", mStartCaptureSem.Count());
741        return NO_INIT;
742        }
743
744    // Camera framework doesn't expect face callbacks once capture is triggered
745    pauseFaceDetection(true);
746
747    //During bracketing image capture is already active
748    {
749    Mutex::Autolock lock(mBracketingLock);
750    if ( mBracketingEnabled )
751        {
752        //Stop bracketing, activate normal burst for the remaining images
753        mBracketingEnabled = false;
754        mCapturedFrames = mBracketingRange;
755        ret = sendBracketFrames();
756        if(ret != NO_ERROR)
757            goto EXIT;
758        else
759            return ret;
760        }
761    }
762
763    if ( NO_ERROR == ret ) {
764        if (mPendingCaptureSettings & SetRotation) {
765            mPendingCaptureSettings &= ~SetRotation;
766            ret = setPictureRotation(mPictureRotation);
767            if ( NO_ERROR != ret ) {
768                CAMHAL_LOGEB("Error configuring image rotation %x", ret);
769            }
770        }
771    }
772
773    //OMX shutter callback events are only available in hq mode
774    if ( (HIGH_QUALITY == mCapMode) || (HIGH_QUALITY_ZSL== mCapMode))
775        {
776
777        if ( NO_ERROR == ret )
778            {
779            ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
780                                        (OMX_EVENTTYPE) OMX_EventIndexSettingChanged,
781                                        OMX_ALL,
782                                        OMX_TI_IndexConfigShutterCallback,
783                                        mStartCaptureSem);
784            }
785
786        if ( NO_ERROR == ret )
787            {
788            ret = setShutterCallback(true);
789            }
790
791        }
792
793    if ( NO_ERROR == ret ) {
794        capData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
795
796        ///Queue all the buffers on capture port
797        for ( int index = 0 ; index < capData->mNumBufs ; index++ ) {
798            CAMHAL_LOGDB("Queuing buffer on Capture port - 0x%x",
799                         ( unsigned int ) capData->mBufferHeader[index]->pBuffer);
800            eError = OMX_FillThisBuffer(mCameraAdapterParameters.mHandleComp,
801                        (OMX_BUFFERHEADERTYPE*)capData->mBufferHeader[index]);
802
803            GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
804        }
805
806        mWaitingForSnapshot = true;
807        mCaptureSignalled = false;
808
809        // Capturing command is not needed when capturing in video mode
810        // Only need to queue buffers on image ports
811        if (mCapMode != VIDEO_MODE) {
812            OMX_INIT_STRUCT_PTR (&bOMX, OMX_CONFIG_BOOLEANTYPE);
813            bOMX.bEnabled = OMX_TRUE;
814
815            /// sending Capturing Command to the component
816            eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
817                                   OMX_IndexConfigCapturing,
818                                   &bOMX);
819
820            CAMHAL_LOGDB("Capture set - 0x%x", eError);
821
822            GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
823        }
824    }
825
826    //OMX shutter callback events are only available in hq mode
827    if ( (HIGH_QUALITY == mCapMode) || (HIGH_QUALITY_ZSL== mCapMode))
828        {
829
830        if ( NO_ERROR == ret )
831            {
832            ret = mStartCaptureSem.WaitTimeout(OMX_CAPTURE_TIMEOUT);
833            }
834
835        //If somethiing bad happened while we wait
836        if (mComponentState == OMX_StateInvalid)
837          {
838            CAMHAL_LOGEA("Invalid State after Image Capture Exitting!!!");
839            goto EXIT;
840          }
841
842        if ( NO_ERROR == ret )
843            {
844            CAMHAL_LOGDA("Shutter callback received");
845            notifyShutterSubscribers();
846            }
847        else
848            {
849            ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
850                               (OMX_EVENTTYPE) OMX_EventIndexSettingChanged,
851                               OMX_ALL,
852                               OMX_TI_IndexConfigShutterCallback,
853                               NULL);
854            CAMHAL_LOGEA("Timeout expired on shutter callback");
855            goto EXIT;
856            }
857
858        }
859
860    return (ret | ErrorUtils::omxToAndroidError(eError));
861
862EXIT:
863    CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
864    mWaitingForSnapshot = false;
865    mCaptureSignalled = false;
866    performCleanupAfterError();
867    LOG_FUNCTION_NAME_EXIT;
868    return (ret | ErrorUtils::omxToAndroidError(eError));
869}
870
871status_t OMXCameraAdapter::stopImageCapture()
872{
873    status_t ret = NO_ERROR;
874    OMX_ERRORTYPE eError = OMX_ErrorNone;
875    OMX_CONFIG_BOOLEANTYPE bOMX;
876    OMXCameraPortParameters *imgCaptureData = NULL;
877
878    LOG_FUNCTION_NAME;
879
880    if (!mCaptureConfigured) {
881        //Capture is not ongoing, return from here
882        return NO_ERROR;
883    }
884
885    if ( 0 != mStopCaptureSem.Count() ) {
886        CAMHAL_LOGEB("Error mStopCaptureSem semaphore count %d", mStopCaptureSem.Count());
887        goto EXIT;
888    }
889
890    //Disable the callback first
891    mWaitingForSnapshot = false;
892    mSnapshotCount = 0;
893
894    // OMX shutter callback events are only available in hq mode
895    if ((HIGH_QUALITY == mCapMode) || (HIGH_QUALITY_ZSL== mCapMode)) {
896        //Disable the callback first
897        ret = setShutterCallback(false);
898
899        // if anybody is waiting on the shutter callback
900        // signal them and then recreate the semaphore
901        if ( 0 != mStartCaptureSem.Count() ) {
902            for (int i = mStopCaptureSem.Count(); i > 0; i--) {
903                ret |= SignalEvent(mCameraAdapterParameters.mHandleComp,
904                                   (OMX_EVENTTYPE) OMX_EventIndexSettingChanged,
905                                   OMX_ALL,
906                                   OMX_TI_IndexConfigShutterCallback,
907                                   NULL );
908            }
909            mStartCaptureSem.Create(0);
910        }
911    }
912
913    // After capture, face detection should be disabled
914    // and application needs to restart face detection
915    stopFaceDetection();
916
917    //Wait here for the capture to be done, in worst case timeout and proceed with cleanup
918    mCaptureSem.WaitTimeout(OMX_CAPTURE_TIMEOUT);
919
920    //If somethiing bad happened while we wait
921    if (mComponentState == OMX_StateInvalid)
922      {
923        CAMHAL_LOGEA("Invalid State Image Capture Stop Exitting!!!");
924        goto EXIT;
925      }
926
927    // Disable image capture
928    // Capturing command is not needed when capturing in video mode
929    if (mCapMode != VIDEO_MODE) {
930        OMX_INIT_STRUCT_PTR (&bOMX, OMX_CONFIG_BOOLEANTYPE);
931        bOMX.bEnabled = OMX_FALSE;
932        imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
933        eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
934                               OMX_IndexConfigCapturing,
935                               &bOMX);
936        if ( OMX_ErrorNone != eError ) {
937            CAMHAL_LOGDB("Error during SetConfig- 0x%x", eError);
938            ret = -1;
939            goto EXIT;
940        }
941    }
942    CAMHAL_LOGDB("Capture set - 0x%x", eError);
943
944    mCaptureSignalled = true; //set this to true if we exited because of timeout
945
946    {
947        Mutex::Autolock lock(mFrameCountMutex);
948        mFrameCount = 0;
949        mFirstFrameCondition.broadcast();
950    }
951
952    return (ret | ErrorUtils::omxToAndroidError(eError));
953
954EXIT:
955    CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
956    //Release image buffers
957    if ( NULL != mReleaseImageBuffersCallback ) {
958        mReleaseImageBuffersCallback(mReleaseData);
959    }
960
961    {
962        Mutex::Autolock lock(mFrameCountMutex);
963        mFrameCount = 0;
964        mFirstFrameCondition.broadcast();
965    }
966
967    performCleanupAfterError();
968    LOG_FUNCTION_NAME_EXIT;
969    return (ret | ErrorUtils::omxToAndroidError(eError));
970}
971
972status_t OMXCameraAdapter::disableImagePort(){
973    status_t ret = NO_ERROR;
974    OMX_ERRORTYPE eError = OMX_ErrorNone;
975    OMXCameraPortParameters *imgCaptureData = NULL;
976
977    if (!mCaptureConfigured) {
978        return NO_ERROR;
979    }
980
981    mCaptureConfigured = false;
982    imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
983
984    ///Register for Image port Disable event
985    ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
986                                OMX_EventCmdComplete,
987                                OMX_CommandPortDisable,
988                                mCameraAdapterParameters.mImagePortIndex,
989                                mStopCaptureSem);
990    ///Disable Capture Port
991    eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
992                                OMX_CommandPortDisable,
993                                mCameraAdapterParameters.mImagePortIndex,
994                                NULL);
995
996    ///Free all the buffers on capture port
997    if (imgCaptureData) {
998        CAMHAL_LOGDB("Freeing buffer on Capture port - %d", imgCaptureData->mNumBufs);
999        for ( int index = 0 ; index < imgCaptureData->mNumBufs ; index++) {
1000            CAMHAL_LOGDB("Freeing buffer on Capture port - 0x%x",
1001                         ( unsigned int ) imgCaptureData->mBufferHeader[index]->pBuffer);
1002            eError = OMX_FreeBuffer(mCameraAdapterParameters.mHandleComp,
1003                                    mCameraAdapterParameters.mImagePortIndex,
1004                                    (OMX_BUFFERHEADERTYPE*)imgCaptureData->mBufferHeader[index]);
1005
1006            GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1007        }
1008    }
1009    CAMHAL_LOGDA("Waiting for port disable");
1010    //Wait for the image port enable event
1011    ret = mStopCaptureSem.WaitTimeout(OMX_CMD_TIMEOUT);
1012
1013    //If somethiing bad happened while we wait
1014    if (mComponentState == OMX_StateInvalid)
1015      {
1016        CAMHAL_LOGEA("Invalid State after Disable Image Port Exitting!!!");
1017        goto EXIT;
1018      }
1019
1020    if ( NO_ERROR == ret ) {
1021        CAMHAL_LOGDA("Port disabled");
1022    } else {
1023        ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
1024                           OMX_EventCmdComplete,
1025                           OMX_CommandPortDisable,
1026                           mCameraAdapterParameters.mImagePortIndex,
1027                           NULL);
1028        CAMHAL_LOGDA("Timeout expired on port disable");
1029        goto EXIT;
1030    }
1031
1032 EXIT:
1033    return (ret | ErrorUtils::omxToAndroidError(eError));
1034}
1035
1036
1037status_t OMXCameraAdapter::UseBuffersCapture(void* bufArr, int num)
1038{
1039    LOG_FUNCTION_NAME;
1040
1041    status_t ret = NO_ERROR;
1042    OMX_ERRORTYPE eError = OMX_ErrorNone;
1043    OMXCameraPortParameters * imgCaptureData = NULL;
1044    uint32_t *buffers = (uint32_t*)bufArr;
1045    OMXCameraPortParameters cap;
1046
1047    imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
1048
1049    if ( 0 != mUseCaptureSem.Count() )
1050        {
1051        CAMHAL_LOGEB("Error mUseCaptureSem semaphore count %d", mUseCaptureSem.Count());
1052        return BAD_VALUE;
1053        }
1054
1055    // capture is already configured...we can skip this step
1056    if (mCaptureConfigured) {
1057
1058        if ( NO_ERROR == ret )
1059            {
1060            ret = setupEXIF();
1061            if ( NO_ERROR != ret )
1062                {
1063                CAMHAL_LOGEB("Error configuring EXIF Buffer %x", ret);
1064                }
1065            }
1066
1067        mCapturedFrames = mBurstFrames;
1068        return NO_ERROR;
1069    }
1070
1071    imgCaptureData->mNumBufs = num;
1072
1073    //TODO: Support more pixelformats
1074
1075    CAMHAL_LOGDB("Params Width = %d", (int)imgCaptureData->mWidth);
1076    CAMHAL_LOGDB("Params Height = %d", (int)imgCaptureData->mWidth);
1077
1078    if (mPendingCaptureSettings & SetFormat) {
1079        mPendingCaptureSettings &= ~SetFormat;
1080        ret = setFormat(OMX_CAMERA_PORT_IMAGE_OUT_IMAGE, *imgCaptureData);
1081        if ( ret != NO_ERROR ) {
1082            CAMHAL_LOGEB("setFormat() failed %d", ret);
1083            LOG_FUNCTION_NAME_EXIT;
1084            return ret;
1085        }
1086    }
1087
1088    if (mPendingCaptureSettings & SetThumb) {
1089        mPendingCaptureSettings &= ~SetThumb;
1090        ret = setThumbnailParams(mThumbWidth, mThumbHeight, mThumbQuality);
1091        if ( NO_ERROR != ret) {
1092            CAMHAL_LOGEB("Error configuring thumbnail size %x", ret);
1093            return ret;
1094        }
1095    }
1096
1097    if (mPendingCaptureSettings & SetExpBracket) {
1098        mPendingCaptureSettings &= ~SetExpBracket;
1099        ret = setExposureBracketing( mExposureBracketingValues,
1100                                     mExposureBracketingValidEntries, mBurstFrames);
1101        if ( ret != NO_ERROR ) {
1102            CAMHAL_LOGEB("setExposureBracketing() failed %d", ret);
1103            goto EXIT;
1104        }
1105    }
1106
1107    if (mPendingCaptureSettings & SetQuality) {
1108        mPendingCaptureSettings &= ~SetQuality;
1109        ret = setImageQuality(mPictureQuality);
1110        if ( NO_ERROR != ret) {
1111            CAMHAL_LOGEB("Error configuring image quality %x", ret);
1112            goto EXIT;
1113        }
1114    }
1115
1116    ///Register for Image port ENABLE event
1117    ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
1118                           OMX_EventCmdComplete,
1119                           OMX_CommandPortEnable,
1120                           mCameraAdapterParameters.mImagePortIndex,
1121                           mUseCaptureSem);
1122
1123    ///Enable Capture Port
1124    eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
1125                             OMX_CommandPortEnable,
1126                             mCameraAdapterParameters.mImagePortIndex,
1127                             NULL);
1128
1129    CAMHAL_LOGDB("OMX_UseBuffer = 0x%x", eError);
1130    GOTO_EXIT_IF(( eError != OMX_ErrorNone ), eError);
1131
1132    for ( int index = 0 ; index < imgCaptureData->mNumBufs ; index++ )
1133    {
1134        OMX_BUFFERHEADERTYPE *pBufferHdr;
1135        CAMHAL_LOGDB("OMX_UseBuffer Capture address: 0x%x, size = %d",
1136                     (unsigned int)buffers[index],
1137                     (int)imgCaptureData->mBufSize);
1138
1139        eError = OMX_UseBuffer(mCameraAdapterParameters.mHandleComp,
1140                               &pBufferHdr,
1141                               mCameraAdapterParameters.mImagePortIndex,
1142                               0,
1143                               mCaptureBuffersLength,
1144                               (OMX_U8*)buffers[index]);
1145
1146        CAMHAL_LOGDB("OMX_UseBuffer = 0x%x", eError);
1147        GOTO_EXIT_IF(( eError != OMX_ErrorNone ), eError);
1148
1149        pBufferHdr->pAppPrivate = (OMX_PTR) index;
1150        pBufferHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
1151        pBufferHdr->nVersion.s.nVersionMajor = 1 ;
1152        pBufferHdr->nVersion.s.nVersionMinor = 1 ;
1153        pBufferHdr->nVersion.s.nRevision = 0;
1154        pBufferHdr->nVersion.s.nStep =  0;
1155        imgCaptureData->mBufferHeader[index] = pBufferHdr;
1156    }
1157
1158    //Wait for the image port enable event
1159    CAMHAL_LOGDA("Waiting for port enable");
1160    ret = mUseCaptureSem.WaitTimeout(OMX_CMD_TIMEOUT);
1161
1162    //If somethiing bad happened while we wait
1163    if (mComponentState == OMX_StateInvalid)
1164      {
1165        CAMHAL_LOGEA("Invalid State after Enable Image Port Exitting!!!");
1166        goto EXIT;
1167      }
1168
1169    if ( ret == NO_ERROR )
1170        {
1171        CAMHAL_LOGDA("Port enabled");
1172        }
1173    else
1174        {
1175        ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
1176                           OMX_EventCmdComplete,
1177                           OMX_CommandPortEnable,
1178                           mCameraAdapterParameters.mImagePortIndex,
1179                           NULL);
1180        CAMHAL_LOGDA("Timeout expired on port enable");
1181        goto EXIT;
1182        }
1183
1184    if ( NO_ERROR == ret )
1185        {
1186        ret = setupEXIF();
1187        if ( NO_ERROR != ret )
1188            {
1189            CAMHAL_LOGEB("Error configuring EXIF Buffer %x", ret);
1190            }
1191        }
1192
1193    mCapturedFrames = mBurstFrames;
1194    mCaptureConfigured = true;
1195
1196    return (ret | ErrorUtils::omxToAndroidError(eError));
1197
1198EXIT:
1199    CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
1200    //Release image buffers
1201    if ( NULL != mReleaseImageBuffersCallback ) {
1202        mReleaseImageBuffersCallback(mReleaseData);
1203    }
1204    performCleanupAfterError();
1205    LOG_FUNCTION_NAME_EXIT;
1206    return (ret | ErrorUtils::omxToAndroidError(eError));
1207
1208}
1209
1210};
1211