OMXCapture.cpp revision 3ec18006399d61e97382601d14aaa43ee339c8b6
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    if ((getNextState() & (CAPTURE_ACTIVE|BRACKETING_ACTIVE)) == 0) {
745        CAMHAL_LOGDA("trying starting capture when already canceled");
746        return NO_ERROR;
747    }
748
749    // Camera framework doesn't expect face callbacks once capture is triggered
750    pauseFaceDetection(true);
751
752    //During bracketing image capture is already active
753    {
754    Mutex::Autolock lock(mBracketingLock);
755    if ( mBracketingEnabled )
756        {
757        //Stop bracketing, activate normal burst for the remaining images
758        mBracketingEnabled = false;
759        mCapturedFrames = mBracketingRange;
760        ret = sendBracketFrames();
761        if(ret != NO_ERROR)
762            goto EXIT;
763        else
764            return ret;
765        }
766    }
767
768    if ( NO_ERROR == ret ) {
769        if (mPendingCaptureSettings & SetRotation) {
770            mPendingCaptureSettings &= ~SetRotation;
771            ret = setPictureRotation(mPictureRotation);
772            if ( NO_ERROR != ret ) {
773                CAMHAL_LOGEB("Error configuring image rotation %x", ret);
774            }
775        }
776    }
777
778    //OMX shutter callback events are only available in hq mode
779    if ( (HIGH_QUALITY == mCapMode) || (HIGH_QUALITY_ZSL== mCapMode))
780        {
781
782        if ( NO_ERROR == ret )
783            {
784            ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
785                                        (OMX_EVENTTYPE) OMX_EventIndexSettingChanged,
786                                        OMX_ALL,
787                                        OMX_TI_IndexConfigShutterCallback,
788                                        mStartCaptureSem);
789            }
790
791        if ( NO_ERROR == ret )
792            {
793            ret = setShutterCallback(true);
794            }
795
796        }
797
798    if ( NO_ERROR == ret ) {
799        capData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
800
801        ///Queue all the buffers on capture port
802        for ( int index = 0 ; index < capData->mNumBufs ; index++ ) {
803            CAMHAL_LOGDB("Queuing buffer on Capture port - 0x%x",
804                         ( unsigned int ) capData->mBufferHeader[index]->pBuffer);
805            eError = OMX_FillThisBuffer(mCameraAdapterParameters.mHandleComp,
806                        (OMX_BUFFERHEADERTYPE*)capData->mBufferHeader[index]);
807
808            GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
809        }
810
811        mWaitingForSnapshot = true;
812        mCaptureSignalled = false;
813
814        // Capturing command is not needed when capturing in video mode
815        // Only need to queue buffers on image ports
816        if (mCapMode != VIDEO_MODE) {
817            OMX_INIT_STRUCT_PTR (&bOMX, OMX_CONFIG_BOOLEANTYPE);
818            bOMX.bEnabled = OMX_TRUE;
819
820            /// sending Capturing Command to the component
821            eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
822                                   OMX_IndexConfigCapturing,
823                                   &bOMX);
824
825            CAMHAL_LOGDB("Capture set - 0x%x", eError);
826
827            GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
828        }
829    }
830
831    //OMX shutter callback events are only available in hq mode
832    if ( (HIGH_QUALITY == mCapMode) || (HIGH_QUALITY_ZSL== mCapMode))
833        {
834
835        if ( NO_ERROR == ret )
836            {
837            ret = mStartCaptureSem.WaitTimeout(OMX_CAPTURE_TIMEOUT);
838            }
839
840        //If somethiing bad happened while we wait
841        if (mComponentState == OMX_StateInvalid)
842          {
843            CAMHAL_LOGEA("Invalid State after Image Capture Exitting!!!");
844            goto EXIT;
845          }
846
847        if ( NO_ERROR == ret )
848            {
849            CAMHAL_LOGDA("Shutter callback received");
850            notifyShutterSubscribers();
851            }
852        else
853            {
854            ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
855                               (OMX_EVENTTYPE) OMX_EventIndexSettingChanged,
856                               OMX_ALL,
857                               OMX_TI_IndexConfigShutterCallback,
858                               NULL);
859            CAMHAL_LOGEA("Timeout expired on shutter callback");
860            goto EXIT;
861            }
862
863        }
864
865    return (ret | ErrorUtils::omxToAndroidError(eError));
866
867EXIT:
868    CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
869    mWaitingForSnapshot = false;
870    mCaptureSignalled = false;
871    performCleanupAfterError();
872    LOG_FUNCTION_NAME_EXIT;
873    return (ret | ErrorUtils::omxToAndroidError(eError));
874}
875
876status_t OMXCameraAdapter::stopImageCapture()
877{
878    status_t ret = NO_ERROR;
879    OMX_ERRORTYPE eError = OMX_ErrorNone;
880    OMX_CONFIG_BOOLEANTYPE bOMX;
881    OMXCameraPortParameters *imgCaptureData = NULL;
882
883    LOG_FUNCTION_NAME;
884
885    if (!mCaptureConfigured) {
886        //Capture is not ongoing, return from here
887        return NO_ERROR;
888    }
889
890    if ( 0 != mStopCaptureSem.Count() ) {
891        CAMHAL_LOGEB("Error mStopCaptureSem semaphore count %d", mStopCaptureSem.Count());
892        goto EXIT;
893    }
894
895    //Disable the callback first
896    mWaitingForSnapshot = false;
897    mSnapshotCount = 0;
898
899    // OMX shutter callback events are only available in hq mode
900    if ((HIGH_QUALITY == mCapMode) || (HIGH_QUALITY_ZSL== mCapMode)) {
901        //Disable the callback first
902        ret = setShutterCallback(false);
903
904        // if anybody is waiting on the shutter callback
905        // signal them and then recreate the semaphore
906        if ( 0 != mStartCaptureSem.Count() ) {
907
908            for (int i = mStartCaptureSem.Count(); i < 0; i++) {
909            ret |= SignalEvent(mCameraAdapterParameters.mHandleComp,
910                               (OMX_EVENTTYPE) OMX_EventIndexSettingChanged,
911                               OMX_ALL,
912                               OMX_TI_IndexConfigShutterCallback,
913                               NULL );
914            }
915            mStartCaptureSem.Create(0);
916        }
917    }
918
919    // After capture, face detection should be disabled
920    // and application needs to restart face detection
921    stopFaceDetection();
922
923    //Wait here for the capture to be done, in worst case timeout and proceed with cleanup
924    mCaptureSem.WaitTimeout(OMX_CAPTURE_TIMEOUT);
925
926    //If somethiing bad happened while we wait
927    if (mComponentState == OMX_StateInvalid)
928      {
929        CAMHAL_LOGEA("Invalid State Image Capture Stop Exitting!!!");
930        goto EXIT;
931      }
932
933    // Disable image capture
934    // Capturing command is not needed when capturing in video mode
935    if (mCapMode != VIDEO_MODE) {
936        OMX_INIT_STRUCT_PTR (&bOMX, OMX_CONFIG_BOOLEANTYPE);
937        bOMX.bEnabled = OMX_FALSE;
938        imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
939        eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
940                               OMX_IndexConfigCapturing,
941                               &bOMX);
942        if ( OMX_ErrorNone != eError ) {
943            CAMHAL_LOGDB("Error during SetConfig- 0x%x", eError);
944            ret = -1;
945            goto EXIT;
946        }
947    }
948    CAMHAL_LOGDB("Capture set - 0x%x", eError);
949
950    mCaptureSignalled = true; //set this to true if we exited because of timeout
951
952    {
953        Mutex::Autolock lock(mFrameCountMutex);
954        mFrameCount = 0;
955        mFirstFrameCondition.broadcast();
956    }
957
958    return (ret | ErrorUtils::omxToAndroidError(eError));
959
960EXIT:
961    CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
962    //Release image buffers
963    if ( NULL != mReleaseImageBuffersCallback ) {
964        mReleaseImageBuffersCallback(mReleaseData);
965    }
966
967    {
968        Mutex::Autolock lock(mFrameCountMutex);
969        mFrameCount = 0;
970        mFirstFrameCondition.broadcast();
971    }
972
973    performCleanupAfterError();
974    LOG_FUNCTION_NAME_EXIT;
975    return (ret | ErrorUtils::omxToAndroidError(eError));
976}
977
978status_t OMXCameraAdapter::disableImagePort(){
979    status_t ret = NO_ERROR;
980    OMX_ERRORTYPE eError = OMX_ErrorNone;
981    OMXCameraPortParameters *imgCaptureData = NULL;
982
983    if (!mCaptureConfigured) {
984        return NO_ERROR;
985    }
986
987    mCaptureConfigured = false;
988    imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
989
990    ///Register for Image port Disable event
991    ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
992                                OMX_EventCmdComplete,
993                                OMX_CommandPortDisable,
994                                mCameraAdapterParameters.mImagePortIndex,
995                                mStopCaptureSem);
996    ///Disable Capture Port
997    eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
998                                OMX_CommandPortDisable,
999                                mCameraAdapterParameters.mImagePortIndex,
1000                                NULL);
1001
1002    ///Free all the buffers on capture port
1003    if (imgCaptureData) {
1004        CAMHAL_LOGDB("Freeing buffer on Capture port - %d", imgCaptureData->mNumBufs);
1005        for ( int index = 0 ; index < imgCaptureData->mNumBufs ; index++) {
1006            CAMHAL_LOGDB("Freeing buffer on Capture port - 0x%x",
1007                         ( unsigned int ) imgCaptureData->mBufferHeader[index]->pBuffer);
1008            eError = OMX_FreeBuffer(mCameraAdapterParameters.mHandleComp,
1009                                    mCameraAdapterParameters.mImagePortIndex,
1010                                    (OMX_BUFFERHEADERTYPE*)imgCaptureData->mBufferHeader[index]);
1011
1012            GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1013        }
1014    }
1015    CAMHAL_LOGDA("Waiting for port disable");
1016    //Wait for the image port enable event
1017    ret = mStopCaptureSem.WaitTimeout(OMX_CMD_TIMEOUT);
1018
1019    //If somethiing bad happened while we wait
1020    if (mComponentState == OMX_StateInvalid)
1021      {
1022        CAMHAL_LOGEA("Invalid State after Disable Image Port Exitting!!!");
1023        goto EXIT;
1024      }
1025
1026    if ( NO_ERROR == ret ) {
1027        CAMHAL_LOGDA("Port disabled");
1028    } else {
1029        ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
1030                           OMX_EventCmdComplete,
1031                           OMX_CommandPortDisable,
1032                           mCameraAdapterParameters.mImagePortIndex,
1033                           NULL);
1034        CAMHAL_LOGDA("Timeout expired on port disable");
1035        goto EXIT;
1036    }
1037
1038 EXIT:
1039    return (ret | ErrorUtils::omxToAndroidError(eError));
1040}
1041
1042
1043status_t OMXCameraAdapter::UseBuffersCapture(void* bufArr, int num)
1044{
1045    LOG_FUNCTION_NAME;
1046
1047    status_t ret = NO_ERROR;
1048    OMX_ERRORTYPE eError = OMX_ErrorNone;
1049    OMXCameraPortParameters * imgCaptureData = NULL;
1050    uint32_t *buffers = (uint32_t*)bufArr;
1051    OMXCameraPortParameters cap;
1052
1053    imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
1054
1055    if ( 0 != mUseCaptureSem.Count() )
1056        {
1057        CAMHAL_LOGEB("Error mUseCaptureSem semaphore count %d", mUseCaptureSem.Count());
1058        return BAD_VALUE;
1059        }
1060
1061    // capture is already configured...we can skip this step
1062    if (mCaptureConfigured) {
1063
1064        if ( NO_ERROR == ret )
1065            {
1066            ret = setupEXIF();
1067            if ( NO_ERROR != ret )
1068                {
1069                CAMHAL_LOGEB("Error configuring EXIF Buffer %x", ret);
1070                }
1071            }
1072
1073        mCapturedFrames = mBurstFrames;
1074        return NO_ERROR;
1075    }
1076
1077    imgCaptureData->mNumBufs = num;
1078
1079    //TODO: Support more pixelformats
1080
1081    CAMHAL_LOGDB("Params Width = %d", (int)imgCaptureData->mWidth);
1082    CAMHAL_LOGDB("Params Height = %d", (int)imgCaptureData->mWidth);
1083
1084    if (mPendingCaptureSettings & SetFormat) {
1085        mPendingCaptureSettings &= ~SetFormat;
1086        ret = setFormat(OMX_CAMERA_PORT_IMAGE_OUT_IMAGE, *imgCaptureData);
1087        if ( ret != NO_ERROR ) {
1088            CAMHAL_LOGEB("setFormat() failed %d", ret);
1089            LOG_FUNCTION_NAME_EXIT;
1090            return ret;
1091        }
1092    }
1093
1094    if (mPendingCaptureSettings & SetThumb) {
1095        mPendingCaptureSettings &= ~SetThumb;
1096        ret = setThumbnailParams(mThumbWidth, mThumbHeight, mThumbQuality);
1097        if ( NO_ERROR != ret) {
1098            CAMHAL_LOGEB("Error configuring thumbnail size %x", ret);
1099            return ret;
1100        }
1101    }
1102
1103    if (mPendingCaptureSettings & SetExpBracket) {
1104        mPendingCaptureSettings &= ~SetExpBracket;
1105        ret = setExposureBracketing( mExposureBracketingValues,
1106                                     mExposureBracketingValidEntries, mBurstFrames);
1107        if ( ret != NO_ERROR ) {
1108            CAMHAL_LOGEB("setExposureBracketing() failed %d", ret);
1109            goto EXIT;
1110        }
1111    }
1112
1113    if (mPendingCaptureSettings & SetQuality) {
1114        mPendingCaptureSettings &= ~SetQuality;
1115        ret = setImageQuality(mPictureQuality);
1116        if ( NO_ERROR != ret) {
1117            CAMHAL_LOGEB("Error configuring image quality %x", ret);
1118            goto EXIT;
1119        }
1120    }
1121
1122    ///Register for Image port ENABLE event
1123    ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
1124                           OMX_EventCmdComplete,
1125                           OMX_CommandPortEnable,
1126                           mCameraAdapterParameters.mImagePortIndex,
1127                           mUseCaptureSem);
1128
1129    ///Enable Capture Port
1130    eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
1131                             OMX_CommandPortEnable,
1132                             mCameraAdapterParameters.mImagePortIndex,
1133                             NULL);
1134
1135    CAMHAL_LOGDB("OMX_UseBuffer = 0x%x", eError);
1136    GOTO_EXIT_IF(( eError != OMX_ErrorNone ), eError);
1137
1138    for ( int index = 0 ; index < imgCaptureData->mNumBufs ; index++ )
1139    {
1140        OMX_BUFFERHEADERTYPE *pBufferHdr;
1141        CAMHAL_LOGDB("OMX_UseBuffer Capture address: 0x%x, size = %d",
1142                     (unsigned int)buffers[index],
1143                     (int)imgCaptureData->mBufSize);
1144
1145        eError = OMX_UseBuffer(mCameraAdapterParameters.mHandleComp,
1146                               &pBufferHdr,
1147                               mCameraAdapterParameters.mImagePortIndex,
1148                               0,
1149                               mCaptureBuffersLength,
1150                               (OMX_U8*)buffers[index]);
1151
1152        CAMHAL_LOGDB("OMX_UseBuffer = 0x%x", eError);
1153        GOTO_EXIT_IF(( eError != OMX_ErrorNone ), eError);
1154
1155        pBufferHdr->pAppPrivate = (OMX_PTR) index;
1156        pBufferHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
1157        pBufferHdr->nVersion.s.nVersionMajor = 1 ;
1158        pBufferHdr->nVersion.s.nVersionMinor = 1 ;
1159        pBufferHdr->nVersion.s.nRevision = 0;
1160        pBufferHdr->nVersion.s.nStep =  0;
1161        imgCaptureData->mBufferHeader[index] = pBufferHdr;
1162    }
1163
1164    //Wait for the image port enable event
1165    CAMHAL_LOGDA("Waiting for port enable");
1166    ret = mUseCaptureSem.WaitTimeout(OMX_CMD_TIMEOUT);
1167
1168    //If somethiing bad happened while we wait
1169    if (mComponentState == OMX_StateInvalid)
1170      {
1171        CAMHAL_LOGEA("Invalid State after Enable Image Port Exitting!!!");
1172        goto EXIT;
1173      }
1174
1175    if ( ret == NO_ERROR )
1176        {
1177        CAMHAL_LOGDA("Port enabled");
1178        }
1179    else
1180        {
1181        ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
1182                           OMX_EventCmdComplete,
1183                           OMX_CommandPortEnable,
1184                           mCameraAdapterParameters.mImagePortIndex,
1185                           NULL);
1186        CAMHAL_LOGDA("Timeout expired on port enable");
1187        goto EXIT;
1188        }
1189
1190    if ( NO_ERROR == ret )
1191        {
1192        ret = setupEXIF();
1193        if ( NO_ERROR != ret )
1194            {
1195            CAMHAL_LOGEB("Error configuring EXIF Buffer %x", ret);
1196            }
1197        }
1198
1199    mCapturedFrames = mBurstFrames;
1200    mCaptureConfigured = true;
1201
1202    return (ret | ErrorUtils::omxToAndroidError(eError));
1203
1204EXIT:
1205    CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
1206    //Release image buffers
1207    if ( NULL != mReleaseImageBuffersCallback ) {
1208        mReleaseImageBuffersCallback(mReleaseData);
1209    }
1210    performCleanupAfterError();
1211    LOG_FUNCTION_NAME_EXIT;
1212    return (ret | ErrorUtils::omxToAndroidError(eError));
1213
1214}
1215
1216};
1217