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#include "CameraHal.h"
25#include "OMXCameraAdapter.h"
26#include "ErrorUtils.h"
27
28
29namespace Ti {
30namespace Camera {
31
32status_t OMXCameraAdapter::setParametersCapture(const android::CameraParameters &params,
33                                                BaseCameraAdapter::AdapterState state)
34{
35    status_t ret = NO_ERROR;
36    const char *str = NULL;
37    int w, h;
38    OMX_COLOR_FORMATTYPE pixFormat;
39    CodingMode codingMode = mCodingMode;
40    const char *valstr = NULL;
41    int varint = 0;
42    OMX_TI_STEREOFRAMELAYOUTTYPE capFrmLayout;
43    bool inCaptureState = false;
44
45    LOG_FUNCTION_NAME;
46
47    OMXCameraPortParameters *cap;
48    cap = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
49
50    capFrmLayout = cap->mFrameLayoutType;
51    setParamS3D(mCameraAdapterParameters.mImagePortIndex,
52        params.get(TICameraParameters::KEY_S3D_CAP_FRAME_LAYOUT));
53    if (capFrmLayout != cap->mFrameLayoutType) {
54        mPendingCaptureSettings |= SetFormat;
55    }
56
57    params.getPictureSize(&w, &h);
58
59    if ( ( w != ( int ) cap->mWidth ) ||
60          ( h != ( int ) cap->mHeight ) )
61        {
62        mPendingCaptureSettings |= SetFormat;
63        }
64
65    cap->mWidth = w;
66    cap->mHeight = h;
67    //TODO: Support more pixelformats
68    //cap->mStride = 2;
69
70    CAMHAL_LOGVB("Image: cap.mWidth = %d", (int)cap->mWidth);
71    CAMHAL_LOGVB("Image: cap.mHeight = %d", (int)cap->mHeight);
72
73    if ((valstr = params.getPictureFormat()) != NULL) {
74        if (strcmp(valstr, android::CameraParameters::PIXEL_FORMAT_YUV422I) == 0) {
75            CAMHAL_LOGDA("CbYCrY format selected");
76            pixFormat = OMX_COLOR_FormatCbYCrY;
77            mPictureFormatFromClient = android::CameraParameters::PIXEL_FORMAT_YUV422I;
78        } else if(strcmp(valstr, android::CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) {
79            CAMHAL_LOGDA("YUV420SP format selected");
80            pixFormat = OMX_COLOR_FormatYUV420SemiPlanar;
81            mPictureFormatFromClient = android::CameraParameters::PIXEL_FORMAT_YUV420SP;
82        } else if(strcmp(valstr, android::CameraParameters::PIXEL_FORMAT_RGB565) == 0) {
83            CAMHAL_LOGDA("RGB565 format selected");
84            pixFormat = OMX_COLOR_Format16bitRGB565;
85            mPictureFormatFromClient = android::CameraParameters::PIXEL_FORMAT_RGB565;
86        } else if (strcmp(valstr, android::CameraParameters::PIXEL_FORMAT_JPEG) == 0) {
87            CAMHAL_LOGDA("JPEG format selected");
88            pixFormat = OMX_COLOR_FormatUnused;
89            codingMode = CodingJPEG;
90            mPictureFormatFromClient = android::CameraParameters::PIXEL_FORMAT_JPEG;
91        } else if (strcmp(valstr, TICameraParameters::PIXEL_FORMAT_JPS) == 0) {
92            CAMHAL_LOGDA("JPS format selected");
93            pixFormat = OMX_COLOR_FormatUnused;
94            codingMode = CodingJPS;
95            mPictureFormatFromClient = TICameraParameters::PIXEL_FORMAT_JPS;
96        } else if (strcmp(valstr, TICameraParameters::PIXEL_FORMAT_MPO) == 0) {
97            CAMHAL_LOGDA("MPO format selected");
98            pixFormat = OMX_COLOR_FormatUnused;
99            codingMode = CodingMPO;
100            mPictureFormatFromClient = TICameraParameters::PIXEL_FORMAT_MPO;
101        } else if (strcmp(valstr, android::CameraParameters::PIXEL_FORMAT_BAYER_RGGB) == 0) {
102            CAMHAL_LOGDA("RAW Picture format selected");
103            pixFormat = OMX_COLOR_FormatRawBayer10bit;
104            mPictureFormatFromClient = android::CameraParameters::PIXEL_FORMAT_BAYER_RGGB;
105        } else {
106            CAMHAL_LOGEA("Invalid format, JPEG format selected as default");
107            pixFormat = OMX_COLOR_FormatUnused;
108            codingMode = CodingJPEG;
109            mPictureFormatFromClient = NULL;
110        }
111    } else {
112        CAMHAL_LOGEA("Picture format is NULL, defaulting to JPEG");
113        pixFormat = OMX_COLOR_FormatUnused;
114        codingMode = CodingJPEG;
115        mPictureFormatFromClient = NULL;
116    }
117
118#ifdef CAMERAHAL_USE_RAW_IMAGE_SAVING
119    mRawCapture = false;
120    mYuvCapture = false;
121
122    valstr = params.get(TICameraParameters::KEY_CAP_MODE);
123    if ( (!valstr || strcmp(valstr, TICameraParameters::HIGH_QUALITY_MODE) == 0) &&
124            access(kRawImagesOutputDirPath, F_OK) != -1 ) {
125        mRawCapture = true;
126    }
127
128    if (mRawCapture && (access(kYuvImagesOutputDirPath, F_OK) != -1)) {
129        pixFormat = OMX_COLOR_FormatCbYCrY;
130        mYuvCapture = true;
131    }
132#endif
133    // JPEG capture is not supported in video mode by OMX Camera
134    // Set capture format to yuv422i...jpeg encode will
135    // be done on A9
136    valstr = params.get(TICameraParameters::KEY_CAP_MODE);
137    if ( (valstr && ( strcmp(valstr, (const char *) TICameraParameters::VIDEO_MODE) == 0 ||
138                      strcmp(valstr, (const char *) TICameraParameters::VIDEO_MODE_HQ) == 0 ) ) &&
139            (pixFormat == OMX_COLOR_FormatUnused) ) {
140        CAMHAL_LOGDA("Capturing in video mode...selecting yuv422i");
141        pixFormat = OMX_COLOR_FormatCbYCrY;
142    }
143
144    if (pixFormat != cap->mColorFormat || codingMode != mCodingMode) {
145        mPendingCaptureSettings |= SetFormat;
146        cap->mColorFormat = pixFormat;
147        mCodingMode = codingMode;
148    }
149
150#ifdef OMAP_ENHANCEMENT
151    str = params.get(TICameraParameters::KEY_TEMP_BRACKETING);
152    if ( ( str != NULL ) &&
153         ( strcmp(str, android::CameraParameters::TRUE) == 0 ) ) {
154
155        if ( !mBracketingSet ) {
156            mPendingCaptureSettings |= SetBurstExpBracket;
157        }
158
159        mBracketingSet = true;
160    } else {
161
162        if ( mBracketingSet ) {
163            mPendingCaptureSettings |= SetBurstExpBracket;
164        }
165
166        mBracketingSet = false;
167    }
168
169    if ( (str = params.get(TICameraParameters::KEY_EXP_BRACKETING_RANGE)) != NULL ) {
170        parseExpRange(str, mExposureBracketingValues, NULL,
171                      mExposureGainBracketingModes,
172                      EXP_BRACKET_RANGE, mExposureBracketingValidEntries);
173        if (mCapMode == OMXCameraAdapter::CP_CAM) {
174            mExposureBracketMode = OMX_BracketVectorShot;
175        } else {
176            mExposureBracketMode = OMX_BracketExposureRelativeInEV;
177        }
178        mPendingCaptureSettings |= SetBurstExpBracket;
179    } else if ( (str = params.get(TICameraParameters::KEY_EXP_GAIN_BRACKETING_RANGE)) != NULL) {
180        parseExpRange(str, mExposureBracketingValues, mExposureGainBracketingValues,
181                      mExposureGainBracketingModes,
182                      EXP_BRACKET_RANGE, mExposureBracketingValidEntries);
183        if (mCapMode == OMXCameraAdapter::CP_CAM) {
184            mExposureBracketMode = OMX_BracketVectorShot;
185        } else {
186            mExposureBracketMode = OMX_BracketExposureGainAbsolute;
187        }
188        mPendingCaptureSettings |= SetBurstExpBracket;
189    } else {
190        // always set queued shot config in CPCAM mode
191        if (mCapMode == OMXCameraAdapter::CP_CAM) {
192            mExposureBracketMode = OMX_BracketVectorShot;
193            mPendingCaptureSettings |= SetBurstExpBracket;
194        }
195        // if bracketing was previously set...we set again before capturing to clear
196        if (mExposureBracketingValidEntries) {
197            mPendingCaptureSettings |= SetBurstExpBracket;
198            mExposureBracketingValidEntries = 0;
199        }
200    }
201
202    str = params.get(TICameraParameters::KEY_ZOOM_BRACKETING_RANGE);
203    if ( NULL != str ) {
204        parseExpRange(str, mZoomBracketingValues, NULL, NULL,
205                      ZOOM_BRACKET_RANGE, mZoomBracketingValidEntries);
206        mCurrentZoomBracketing = 0;
207        mZoomBracketingEnabled = true;
208    } else {
209        if (mZoomBracketingValidEntries) {
210            mZoomBracketingValidEntries = 0;
211        }
212        mZoomBracketingEnabled = false;
213    }
214#endif
215
216    // Flush config queue
217    // If TRUE: Flush queue and abort processing before enqueing
218    valstr = params.get(TICameraParameters::KEY_FLUSH_SHOT_CONFIG_QUEUE);
219    if ( NULL != valstr ) {
220        if ( 0 == strcmp(valstr, android::CameraParameters::TRUE) ) {
221            mFlushShotConfigQueue = true;
222        } else if ( 0 == strcmp(valstr, android::CameraParameters::FALSE) ) {
223            mFlushShotConfigQueue = false;
224        } else {
225            CAMHAL_LOGE("Missing flush shot config parameter. Will use current (%s)",
226                        mFlushShotConfigQueue ? "true" : "false");
227        }
228    }
229
230    if ( params.getInt(android::CameraParameters::KEY_ROTATION) != -1 )
231        {
232        if (params.getInt(android::CameraParameters::KEY_ROTATION) != (int) mPictureRotation) {
233            mPendingCaptureSettings |= SetRotation;
234        }
235        mPictureRotation = params.getInt(android::CameraParameters::KEY_ROTATION);
236        }
237    else
238        {
239        if (mPictureRotation) mPendingCaptureSettings |= SetRotation;
240        mPictureRotation = 0;
241        }
242
243    CAMHAL_LOGVB("Picture Rotation set %d", mPictureRotation);
244
245#ifdef OMAP_ENHANCEMENT
246    // Read Sensor Orientation and set it based on perating mode
247    varint = params.getInt(TICameraParameters::KEY_SENSOR_ORIENTATION);
248    if ( varint != -1 )
249        {
250        mSensorOrientation = varint;
251        if (mSensorOrientation == 270 ||mSensorOrientation==90)
252            {
253            CAMHAL_LOGEA(" Orientation is 270/90. So setting counter rotation to Ducati");
254            mSensorOrientation +=180;
255            mSensorOrientation%=360;
256            }
257        }
258    else
259        {
260        mSensorOrientation = 0;
261        }
262
263    CAMHAL_LOGVB("Sensor Orientation  set : %d", mSensorOrientation);
264#endif
265
266#ifdef OMAP_ENHANCEMENT_BURST_CAPTURE
267    varint = params.getInt(TICameraParameters::KEY_BURST);
268    if ( varint >= 1 )
269        {
270        if (varint != (int) mBurstFrames) {
271            mPendingCaptureSettings |= SetBurstExpBracket;
272        }
273        mBurstFrames = varint;
274        }
275    else
276        {
277        if (mBurstFrames != 1) mPendingCaptureSettings |= SetBurstExpBracket;
278        mBurstFrames = 1;
279        }
280
281    CAMHAL_LOGVB("Burst Frames set %d", mBurstFrames);
282#endif
283
284    varint = params.getInt(android::CameraParameters::KEY_JPEG_QUALITY);
285    if ( varint >= MIN_JPEG_QUALITY && varint <= MAX_JPEG_QUALITY ) {
286        if (varint != mPictureQuality) {
287            mPendingCaptureSettings |= SetQuality;
288            mPictureQuality = varint;
289        }
290    } else {
291        if (mPictureQuality != MAX_JPEG_QUALITY) {
292            mPendingCaptureSettings |= SetQuality;
293            mPictureQuality = MAX_JPEG_QUALITY;
294        }
295    }
296
297    CAMHAL_LOGVB("Picture Quality set %d", mPictureQuality);
298
299    varint = params.getInt(android::CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
300    if ( varint >= 0 ) {
301        if (varint != mThumbWidth) {
302            mPendingCaptureSettings |= SetThumb;
303            mThumbWidth = varint;
304        }
305    } else {
306        if (mThumbWidth != DEFAULT_THUMB_WIDTH) {
307            mPendingCaptureSettings |= SetThumb;
308            mThumbWidth = DEFAULT_THUMB_WIDTH;
309        }
310    }
311
312    CAMHAL_LOGVB("Picture Thumb width set %d", mThumbWidth);
313
314    varint = params.getInt(android::CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
315    if ( varint >= 0 ) {
316        if (varint != mThumbHeight) {
317            mPendingCaptureSettings |= SetThumb;
318            mThumbHeight = varint;
319        }
320    } else {
321        if (mThumbHeight != DEFAULT_THUMB_HEIGHT) {
322            mPendingCaptureSettings |= SetThumb;
323            mThumbHeight = DEFAULT_THUMB_HEIGHT;
324        }
325    }
326
327    CAMHAL_LOGVB("Picture Thumb height set %d", mThumbHeight);
328
329    varint = params.getInt(android::CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
330    if ( varint >= MIN_JPEG_QUALITY && varint <= MAX_JPEG_QUALITY ) {
331        if (varint != mThumbQuality) {
332            mPendingCaptureSettings |= SetThumb;
333            mThumbQuality = varint;
334        }
335    } else {
336        if (mThumbQuality != MAX_JPEG_QUALITY) {
337            mPendingCaptureSettings |= SetThumb;
338            mThumbQuality = MAX_JPEG_QUALITY;
339        }
340    }
341
342    CAMHAL_LOGDB("Thumbnail Quality set %d", mThumbQuality);
343
344    if (mFirstTimeInit) {
345        mPendingCaptureSettings = ECapturesettingsAll;
346    }
347
348    cap = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoPortIndex];
349    cap->mWidth = params.getInt(TICameraParameters::RAW_WIDTH);
350    cap->mHeight = params.getInt(TICameraParameters::RAW_HEIGHT);
351
352    LOG_FUNCTION_NAME_EXIT;
353
354    return ret;
355}
356
357status_t OMXCameraAdapter::getPictureBufferSize(CameraFrame &frame, size_t bufferCount)
358{
359    status_t ret = NO_ERROR;
360    OMXCameraPortParameters *imgCaptureData = NULL;
361    OMX_ERRORTYPE eError = OMX_ErrorNone;
362
363    LOG_FUNCTION_NAME;
364
365    if ( NO_ERROR == ret )
366        {
367        imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
368
369
370        // If any settings have changed that need to be set with SetParam,
371        // we will need to disable the port to set them
372        if ((mPendingCaptureSettings & ECaptureParamSettings)) {
373            disableImagePort();
374            if ( NULL != mReleaseImageBuffersCallback ) {
375                mReleaseImageBuffersCallback(mReleaseData);
376            }
377        }
378
379        if (mPendingCaptureSettings & SetFormat) {
380            ret = setFormat(OMX_CAMERA_PORT_IMAGE_OUT_IMAGE, *imgCaptureData);
381        }
382
383        if ( ret == NO_ERROR )
384            {
385            frame.mLength = imgCaptureData->mBufSize;
386            frame.mWidth = imgCaptureData->mWidth;
387            frame.mHeight = imgCaptureData->mHeight;
388            frame.mAlignment = imgCaptureData->mStride;
389            CAMHAL_LOGDB("getPictureBufferSize: width:%u height:%u alignment:%u length:%u",
390                         frame.mWidth, frame.mHeight, frame.mAlignment, frame.mLength);
391            }
392        else
393            {
394            CAMHAL_LOGEB("setFormat() failed 0x%x", ret);
395            }
396        }
397
398    LOG_FUNCTION_NAME_EXIT;
399
400    return ret;
401}
402
403int OMXCameraAdapter::getBracketingValueMode(const char *a, const char *b) const
404{
405    BracketingValueMode bvm = BracketingValueAbsolute;
406
407    if ( (NULL != b) &&
408         (NULL != a) &&
409         (a < b) &&
410         ( (NULL != memchr(a, '+', b - a)) ||
411           (NULL != memchr(a, '-', b - a)) ) ) {
412        bvm = BracketingValueRelative;
413    }
414    return bvm;
415}
416
417status_t OMXCameraAdapter::parseExpRange(const char *rangeStr,
418                                         int *expRange,
419                                         int *gainRange,
420                                         int *expGainModes,
421                                         size_t count,
422                                         size_t &validEntries)
423{
424    status_t ret = NO_ERROR;
425    char *end = NULL;
426    const char *startPtr = NULL;
427    size_t i = 0;
428
429    LOG_FUNCTION_NAME;
430
431    if ( NULL == rangeStr ){
432        return -EINVAL;
433    }
434
435    if ( NULL == expRange ){
436        return -EINVAL;
437    }
438
439    if ( NO_ERROR == ret ) {
440        startPtr = rangeStr;
441        do {
442            // Relative Exposure example: "-30,-10, 0, 10, 30"
443            // Absolute Gain ex. (exposure,gain) pairs: "(100,300),(200,300),(400,300),(800,300),(1600,300)"
444            // Relative Gain ex. (exposure,gain) pairs: "(-30,+0),(-10, +0),(+0,+0),(+10,+0),(+30,+0)"
445            // Forced relative Exposure example: "-30F,-10F, 0F, 10F, 30F"
446            // Forced absolute Gain ex. (exposure,gain) pairs: "(100,300)F,(200,300)F,(400,300)F,(800,300)F,(1600,300)F"
447            // Forced relative Gain ex. (exposure,gain) pairs: "(-30,+0)F,(-10, +0)F,(+0,+0)F,(+10,+0)F,(+30,+0)F"
448
449            // skip '(' and ','
450            while ((*startPtr == '(') ||  (*startPtr == ',')) startPtr++;
451
452            expRange[i] = (int)strtol(startPtr, &end, 10);
453
454            if (expGainModes) {
455                // if gainRange is given rangeStr should be (exposure, gain) pair
456                if (gainRange) {
457                    int bvm_exp = getBracketingValueMode(startPtr, end);
458                    startPtr = end + 1; // for the ','
459                    gainRange[i] = (int)strtol(startPtr, &end, 10);
460
461                    if (BracketingValueAbsolute == bvm_exp) {
462                        expGainModes[i] = getBracketingValueMode(startPtr, end);
463                    } else {
464                        expGainModes[i] = bvm_exp;
465                    }
466                } else {
467                    expGainModes[i] = BracketingValueCompensation;
468                }
469            }
470            startPtr = end;
471
472            // skip ')'
473            while (*startPtr == ')') startPtr++;
474
475            // Check for "forced" key
476            if (expGainModes) {
477                while ((*startPtr == 'F') || (*startPtr == 'f')) {
478                    if ( BracketingValueAbsolute == expGainModes[i] ) {
479                        expGainModes[i] = BracketingValueAbsoluteForced;
480                    } else if ( BracketingValueRelative == expGainModes[i] ) {
481                        expGainModes[i] = BracketingValueRelativeForced;
482                    } else if ( BracketingValueCompensation == expGainModes[i] ) {
483                        expGainModes[i] = BracketingValueCompensationForced;
484                    } else {
485                        CAMHAL_LOGE("Unexpected old mode 0x%x", expGainModes[i]);
486                    }
487                    startPtr++;
488                }
489            }
490
491            i++;
492
493        } while ((startPtr[0] != '\0') && (i < count));
494        validEntries = i;
495    }
496
497    LOG_FUNCTION_NAME_EXIT;
498
499    return ret;
500}
501
502status_t OMXCameraAdapter::doExposureBracketing(int *evValues,
503                                                 int *evValues2,
504                                                 int *evModes2,
505                                                 size_t evCount,
506                                                 size_t frameCount,
507                                                 bool flush,
508                                                 OMX_BRACKETMODETYPE bracketMode)
509{
510    status_t ret = NO_ERROR;
511
512    LOG_FUNCTION_NAME;
513
514    if ( OMX_StateInvalid == mComponentState ) {
515        CAMHAL_LOGEA("OMX component is in invalid state");
516        ret = -EINVAL;
517    }
518
519    if ( NULL == evValues ) {
520        CAMHAL_LOGEA("Exposure compensation values pointer is invalid");
521        ret = -EINVAL;
522    }
523
524    if ( NO_ERROR == ret ) {
525        if (bracketMode == OMX_BracketVectorShot) {
526            ret = setVectorShot(evValues, evValues2, evModes2, evCount, frameCount, flush, bracketMode);
527        } else {
528            ret = setExposureBracketing(evValues, evValues2, evCount, frameCount, bracketMode);
529        }
530    }
531
532    LOG_FUNCTION_NAME_EXIT;
533
534    return ret;
535}
536
537status_t OMXCameraAdapter::setVectorStop(bool toPreview)
538{
539    status_t ret = NO_ERROR;
540    OMX_ERRORTYPE eError = OMX_ErrorNone;
541    OMX_TI_CONFIG_VECTSHOTSTOPMETHODTYPE vecShotStop;
542
543
544    LOG_FUNCTION_NAME;
545
546    OMX_INIT_STRUCT_PTR(&vecShotStop, OMX_TI_CONFIG_VECTSHOTSTOPMETHODTYPE);
547
548    vecShotStop.nPortIndex = mCameraAdapterParameters.mImagePortIndex;
549    if (toPreview) {
550        vecShotStop.eStopMethod =  OMX_TI_VECTSHOTSTOPMETHOD_GOTO_PREVIEW;
551    } else {
552        vecShotStop.eStopMethod =  OMX_TI_VECTSHOTSTOPMETHOD_WAIT_IN_CAPTURE;
553    }
554
555    eError =  OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
556                           (OMX_INDEXTYPE) OMX_TI_IndexConfigVectShotStopMethod,
557                           &vecShotStop);
558    if (OMX_ErrorNone != eError) {
559        CAMHAL_LOGEB("Error while configuring bracket shot 0x%x", eError);
560    } else {
561        CAMHAL_LOGDA("Bracket shot configured successfully");
562    }
563
564    LOG_FUNCTION_NAME_EXIT;
565
566    return (ret | Utils::ErrorUtils::omxToAndroidError(eError));
567}
568
569status_t OMXCameraAdapter::initVectorShot()
570{
571    status_t ret = NO_ERROR;
572    OMX_ERRORTYPE eError = OMX_ErrorNone;
573    OMX_CONFIG_CAPTUREMODETYPE expCapMode;
574    OMX_CONFIG_EXTCAPTUREMODETYPE extExpCapMode;
575
576    LOG_FUNCTION_NAME;
577
578    if (NO_ERROR == ret) {
579        OMX_INIT_STRUCT_PTR (&expCapMode, OMX_CONFIG_CAPTUREMODETYPE);
580        expCapMode.nPortIndex = mCameraAdapterParameters.mImagePortIndex;
581
582        expCapMode.bFrameLimited = OMX_FALSE;
583
584        eError =  OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
585                                OMX_IndexConfigCaptureMode,
586                                &expCapMode);
587        if (OMX_ErrorNone != eError) {
588            CAMHAL_LOGEB("Error while configuring capture mode 0x%x", eError);
589            goto exit;
590        } else {
591            CAMHAL_LOGDA("Camera capture mode configured successfully");
592        }
593    }
594
595    if (NO_ERROR == ret) {
596        OMX_INIT_STRUCT_PTR (&extExpCapMode, OMX_CONFIG_EXTCAPTUREMODETYPE);
597        extExpCapMode.nPortIndex = mCameraAdapterParameters.mImagePortIndex;
598
599        extExpCapMode.bEnableBracketing = OMX_TRUE;
600        extExpCapMode.tBracketConfigType.eBracketMode = OMX_BracketVectorShot;
601
602        eError =  OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
603                                ( OMX_INDEXTYPE ) OMX_IndexConfigExtCaptureMode,
604                                &extExpCapMode);
605        if ( OMX_ErrorNone != eError ) {
606            CAMHAL_LOGEB("Error while configuring extended capture mode 0x%x", eError);
607            goto exit;
608        } else {
609            CAMHAL_LOGDA("Extended camera capture mode configured successfully");
610        }
611    }
612
613
614    if (NO_ERROR == ret) {
615        // set vector stop method to stop in capture
616        ret = setVectorStop(false);
617    }
618
619 exit:
620    LOG_FUNCTION_NAME_EXIT;
621
622    return (ret | Utils::ErrorUtils::omxToAndroidError(eError));
623}
624
625status_t OMXCameraAdapter::setVectorShot(int *evValues,
626                                         int *evValues2,
627                                         int *evModes2,
628                                         size_t evCount,
629                                         size_t frameCount,
630                                         bool flush,
631                                         OMX_BRACKETMODETYPE bracketMode)
632{
633    status_t ret = NO_ERROR;
634    OMX_ERRORTYPE eError = OMX_ErrorNone;
635    OMX_TI_CONFIG_ENQUEUESHOTCONFIGS enqueueShotConfigs;
636    OMX_TI_CONFIG_QUERYAVAILABLESHOTS queryAvailableShots;
637    bool doFlush = flush;
638
639    LOG_FUNCTION_NAME;
640
641    OMX_INIT_STRUCT_PTR(&enqueueShotConfigs, OMX_TI_CONFIG_ENQUEUESHOTCONFIGS);
642    OMX_INIT_STRUCT_PTR(&queryAvailableShots, OMX_TI_CONFIG_QUERYAVAILABLESHOTS);
643
644    queryAvailableShots.nPortIndex = mCameraAdapterParameters.mImagePortIndex;
645    eError = OMX_GetConfig(mCameraAdapterParameters.mHandleComp,
646                                (OMX_INDEXTYPE) OMX_TI_IndexConfigQueryAvailableShots,
647                                &queryAvailableShots);
648    if (OMX_ErrorNone != eError) {
649        CAMHAL_LOGE("Error getting available shots 0x%x", eError);
650        goto exit;
651    } else {
652        CAMHAL_LOGD("AVAILABLE SHOTS: %d", queryAvailableShots.nAvailableShots);
653        if (queryAvailableShots.nAvailableShots < evCount) {
654            // TODO(XXX): Need to implement some logic to handle this error
655            CAMHAL_LOGE("Not enough available shots to fulfill this queue request");
656            ret = -ENOSPC;
657            goto exit;
658        }
659    }
660
661    for ( unsigned int confID = 0; confID < evCount; ) {
662        unsigned int i;
663        for ( i = 0 ; (i < ARRAY_SIZE(enqueueShotConfigs.nShotConfig)) && (confID < evCount); i++, confID++ ) {
664                CAMHAL_LOGD("%2u: (%7d,%4d) mode: %d", confID, evValues[confID], evValues2[confID], evModes2[confID]);
665                enqueueShotConfigs.nShotConfig[i].nConfigId = confID;
666                enqueueShotConfigs.nShotConfig[i].nFrames = 1;
667                if ( (BracketingValueCompensation == evModes2[confID]) ||
668                     (BracketingValueCompensationForced == evModes2[confID]) ) {
669                    // EV compensation
670                    enqueueShotConfigs.nShotConfig[i].nEC = evValues[confID];
671                    enqueueShotConfigs.nShotConfig[i].nExp = 0;
672                    enqueueShotConfigs.nShotConfig[i].nGain = 0;
673                } else {
674                    // exposure,gain pair
675                    enqueueShotConfigs.nShotConfig[i].nEC = 0;
676                    enqueueShotConfigs.nShotConfig[i].nExp = evValues[confID];
677                    enqueueShotConfigs.nShotConfig[i].nGain = evValues2[confID];
678                }
679                enqueueShotConfigs.nShotConfig[i].eExpGainApplyMethod = OMX_TI_EXPGAINAPPLYMETHOD_ABSOLUTE;
680                switch (evModes2[confID]) {
681                    case BracketingValueAbsolute: // (exp,gain) pairs directly program sensor values
682                    default :
683                        enqueueShotConfigs.nShotConfig[i].eExpGainApplyMethod = OMX_TI_EXPGAINAPPLYMETHOD_ABSOLUTE;
684                        break;
685                    case BracketingValueRelative: // (exp,gain) pairs relative to AE settings and constraints
686                    case BracketingValueCompensation: // EV compensation relative to AE settings and constraints
687                        enqueueShotConfigs.nShotConfig[i].eExpGainApplyMethod = OMX_TI_EXPGAINAPPLYMETHOD_RELATIVE;
688                        break;
689                    case BracketingValueAbsoluteForced: // (exp,gain) pairs directly program sensor values
690                        // are forced over constraints due to flicker, etc.
691                        enqueueShotConfigs.nShotConfig[i].eExpGainApplyMethod = OMX_TI_EXPGAINAPPLYMETHOD_FORCE_ABSOLUTE;
692                        break;
693                    case BracketingValueRelativeForced: // (exp, gain) pairs relative to AE settings AND settings
694                    case BracketingValueCompensationForced: // EV compensation relative to AE settings and constraints
695                        // are forced over constraints due to flicker, etc.
696                        enqueueShotConfigs.nShotConfig[i].eExpGainApplyMethod = OMX_TI_EXPGAINAPPLYMETHOD_FORCE_RELATIVE;
697                        break;
698                }
699                enqueueShotConfigs.nShotConfig[i].bNoSnapshot = OMX_FALSE; // TODO: Make this configurable
700        }
701
702        // Repeat last exposure and again
703        if ((confID == evCount) && (evCount > 0) && (frameCount > evCount) && (0 != i)) {
704            enqueueShotConfigs.nShotConfig[i-1].nFrames = frameCount - evCount;
705        }
706
707        enqueueShotConfigs.nPortIndex = mCameraAdapterParameters.mImagePortIndex;
708        enqueueShotConfigs.bFlushQueue = doFlush ? OMX_TRUE : OMX_FALSE;
709        enqueueShotConfigs.nNumConfigs = i;
710        eError =  OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
711                        ( OMX_INDEXTYPE ) OMX_TI_IndexConfigEnqueueShotConfigs,
712                            &enqueueShotConfigs);
713        if ( OMX_ErrorNone != eError ) {
714            CAMHAL_LOGEB("Error while configuring enqueue shot 0x%x", eError);
715            goto exit;
716        } else {
717            CAMHAL_LOGDA("Enqueue shot configured successfully");
718        }
719        // Flush only first time
720        doFlush = false;
721    }
722
723    // Handle burst capture (no any bracketing) case
724    if (0 == evCount) {
725        CAMHAL_LOGE("Handle burst capture (no any bracketing) case");
726        enqueueShotConfigs.nShotConfig[0].nConfigId = 0;
727        enqueueShotConfigs.nShotConfig[0].nFrames = frameCount;
728        enqueueShotConfigs.nShotConfig[0].nEC = 0;
729        enqueueShotConfigs.nShotConfig[0].nExp = 0;
730        enqueueShotConfigs.nShotConfig[0].nGain = 0;
731        enqueueShotConfigs.nShotConfig[0].eExpGainApplyMethod = OMX_TI_EXPGAINAPPLYMETHOD_RELATIVE;
732        enqueueShotConfigs.nShotConfig[0].bNoSnapshot = OMX_FALSE; // TODO: Make this configurable
733        enqueueShotConfigs.nNumConfigs = 1;
734        enqueueShotConfigs.nPortIndex = mCameraAdapterParameters.mImagePortIndex;
735        enqueueShotConfigs.bFlushQueue = doFlush ? OMX_TRUE : OMX_FALSE;
736        eError =  OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
737                        ( OMX_INDEXTYPE ) OMX_TI_IndexConfigEnqueueShotConfigs,
738                            &enqueueShotConfigs);
739        if ( OMX_ErrorNone != eError ) {
740            CAMHAL_LOGEB("Error while configuring enqueue shot 0x%x", eError);
741            goto exit;
742        } else {
743            CAMHAL_LOGDA("Enqueue shot configured successfully");
744        }
745    }
746
747 exit:
748    LOG_FUNCTION_NAME_EXIT;
749
750    return (ret | Utils::ErrorUtils::omxToAndroidError(eError));
751}
752
753status_t OMXCameraAdapter::setExposureBracketing(int *evValues,
754                                                 int *evValues2,
755                                                 size_t evCount,
756                                                 size_t frameCount,
757                                                 OMX_BRACKETMODETYPE bracketMode)
758{
759    status_t ret = NO_ERROR;
760    OMX_ERRORTYPE eError = OMX_ErrorNone;
761    OMX_CONFIG_CAPTUREMODETYPE expCapMode;
762    OMX_CONFIG_EXTCAPTUREMODETYPE extExpCapMode;
763
764    LOG_FUNCTION_NAME;
765
766    if ( NO_ERROR == ret )
767        {
768        OMX_INIT_STRUCT_PTR (&expCapMode, OMX_CONFIG_CAPTUREMODETYPE);
769        expCapMode.nPortIndex = mCameraAdapterParameters.mImagePortIndex;
770
771        /// If frameCount>0 but evCount<=0, then this is the case of HQ burst.
772        //Otherwise, it is normal HQ capture
773        ///If frameCount>0 and evCount>0 then this is the cause of HQ Exposure bracketing.
774        if ( 0 == evCount && 0 == frameCount )
775            {
776            expCapMode.bFrameLimited = OMX_FALSE;
777            }
778        else
779            {
780            expCapMode.bFrameLimited = OMX_TRUE;
781            expCapMode.nFrameLimit = frameCount;
782            }
783
784        eError =  OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
785                                OMX_IndexConfigCaptureMode,
786                                &expCapMode);
787        if ( OMX_ErrorNone != eError )
788            {
789            CAMHAL_LOGEB("Error while configuring capture mode 0x%x", eError);
790            }
791        else
792            {
793            CAMHAL_LOGDA("Camera capture mode configured successfully");
794            }
795        }
796
797    if ( NO_ERROR == ret )
798        {
799        OMX_INIT_STRUCT_PTR (&extExpCapMode, OMX_CONFIG_EXTCAPTUREMODETYPE);
800        extExpCapMode.nPortIndex = mCameraAdapterParameters.mImagePortIndex;
801
802        if ( 0 == evCount )
803            {
804            extExpCapMode.bEnableBracketing = OMX_FALSE;
805            }
806        else
807            {
808            extExpCapMode.bEnableBracketing = OMX_TRUE;
809            extExpCapMode.tBracketConfigType.eBracketMode = bracketMode;
810            extExpCapMode.tBracketConfigType.nNbrBracketingValues = evCount - 1;
811            }
812
813        for ( unsigned int i = 0 ; i < evCount ; i++ )
814            {
815            if (bracketMode == OMX_BracketExposureGainAbsolute) {
816                extExpCapMode.tBracketConfigType.nBracketValues[i]  =  evValues[i];
817                extExpCapMode.tBracketConfigType.nBracketValues2[i]  =  evValues2[i];
818            } else {
819                // assuming OMX_BracketExposureRelativeInEV
820                extExpCapMode.tBracketConfigType.nBracketValues[i]  =  ( evValues[i] * ( 1 << Q16_OFFSET ) )  / 10;
821            }
822            }
823
824        eError =  OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
825                                ( OMX_INDEXTYPE ) OMX_IndexConfigExtCaptureMode,
826                                &extExpCapMode);
827        if ( OMX_ErrorNone != eError )
828            {
829            CAMHAL_LOGEB("Error while configuring extended capture mode 0x%x", eError);
830            }
831        else
832            {
833            CAMHAL_LOGDA("Extended camera capture mode configured successfully");
834            }
835        }
836
837    LOG_FUNCTION_NAME_EXIT;
838
839    return ret;
840}
841
842status_t OMXCameraAdapter::setShutterCallback(bool enabled)
843{
844    status_t ret = NO_ERROR;
845    OMX_ERRORTYPE eError = OMX_ErrorNone;
846    OMX_CONFIG_CALLBACKREQUESTTYPE shutterRequstCallback;
847
848    LOG_FUNCTION_NAME;
849
850    if ( OMX_StateExecuting != mComponentState )
851        {
852        CAMHAL_LOGEA("OMX component not in executing state");
853        ret = -1;
854        }
855
856    if ( NO_ERROR == ret )
857        {
858
859        OMX_INIT_STRUCT_PTR (&shutterRequstCallback, OMX_CONFIG_CALLBACKREQUESTTYPE);
860        shutterRequstCallback.nPortIndex = OMX_ALL;
861
862        if ( enabled )
863            {
864            shutterRequstCallback.bEnable = OMX_TRUE;
865            shutterRequstCallback.nIndex = ( OMX_INDEXTYPE ) OMX_TI_IndexConfigShutterCallback;
866            CAMHAL_LOGDA("Enabling shutter callback");
867            }
868        else
869            {
870            shutterRequstCallback.bEnable = OMX_FALSE;
871            shutterRequstCallback.nIndex = ( OMX_INDEXTYPE ) OMX_TI_IndexConfigShutterCallback;
872            CAMHAL_LOGDA("Disabling shutter callback");
873            }
874
875        eError =  OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
876                                ( OMX_INDEXTYPE ) OMX_IndexConfigCallbackRequest,
877                                &shutterRequstCallback);
878        if ( OMX_ErrorNone != eError )
879            {
880            CAMHAL_LOGEB("Error registering shutter callback 0x%x", eError);
881            ret = -1;
882            }
883        else
884            {
885            CAMHAL_LOGDB("Shutter callback for index 0x%x registered successfully",
886                         OMX_TI_IndexConfigShutterCallback);
887            }
888        }
889
890    LOG_FUNCTION_NAME_EXIT;
891
892    return ret;
893}
894
895status_t OMXCameraAdapter::doBracketing(OMX_BUFFERHEADERTYPE *pBuffHeader,
896                                        CameraFrame::FrameType typeOfFrame)
897{
898    status_t ret = NO_ERROR;
899    int currentBufferIdx, nextBufferIdx;
900    OMXCameraPortParameters * imgCaptureData = NULL;
901
902    LOG_FUNCTION_NAME;
903
904    imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
905
906    if ( OMX_StateExecuting != mComponentState )
907        {
908        CAMHAL_LOGEA("OMX component is not in executing state");
909        ret = -EINVAL;
910        }
911
912    if ( NO_ERROR == ret )
913        {
914        CameraBuffer *buffer = (CameraBuffer *)pBuffHeader->pAppPrivate;
915        currentBufferIdx = buffer->index;
916
917        if ( currentBufferIdx >= imgCaptureData->mNumBufs)
918            {
919            CAMHAL_LOGEB("Invalid bracketing buffer index 0x%x", currentBufferIdx);
920            ret = -EINVAL;
921            }
922        }
923
924    if ( NO_ERROR == ret )
925        {
926        mBracketingBuffersQueued[currentBufferIdx] = false;
927        mBracketingBuffersQueuedCount--;
928
929        if ( 0 >= mBracketingBuffersQueuedCount )
930            {
931            nextBufferIdx = ( currentBufferIdx + 1 ) % imgCaptureData->mNumBufs;
932            mBracketingBuffersQueued[nextBufferIdx] = true;
933            mBracketingBuffersQueuedCount++;
934            mLastBracetingBufferIdx = nextBufferIdx;
935            setFrameRefCount((CameraBuffer *)imgCaptureData->mBufferHeader[nextBufferIdx]->pAppPrivate, typeOfFrame, 1);
936            returnFrame((CameraBuffer *)imgCaptureData->mBufferHeader[nextBufferIdx]->pAppPrivate, typeOfFrame);
937            }
938        }
939
940    LOG_FUNCTION_NAME_EXIT;
941
942    return ret;
943}
944
945status_t OMXCameraAdapter::sendBracketFrames(size_t &framesSent)
946{
947    status_t ret = NO_ERROR;
948    int currentBufferIdx;
949    OMXCameraPortParameters * imgCaptureData = NULL;
950
951    LOG_FUNCTION_NAME;
952
953    imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
954    framesSent = 0;
955
956    if ( OMX_StateExecuting != mComponentState )
957        {
958        CAMHAL_LOGEA("OMX component is not in executing state");
959        ret = -EINVAL;
960        }
961
962    if ( NO_ERROR == ret )
963        {
964
965        currentBufferIdx = mLastBracetingBufferIdx;
966        do
967            {
968            currentBufferIdx++;
969            currentBufferIdx %= imgCaptureData->mNumBufs;
970            if (!mBracketingBuffersQueued[currentBufferIdx] )
971                {
972                CameraFrame cameraFrame;
973                sendCallBacks(cameraFrame,
974                              imgCaptureData->mBufferHeader[currentBufferIdx],
975                              imgCaptureData->mImageType,
976                              imgCaptureData);
977                framesSent++;
978                }
979            } while ( currentBufferIdx != mLastBracetingBufferIdx );
980
981        }
982
983    LOG_FUNCTION_NAME_EXIT;
984
985    return ret;
986}
987
988status_t OMXCameraAdapter::startBracketing(int range)
989{
990    status_t ret = NO_ERROR;
991    OMXCameraPortParameters * imgCaptureData = NULL;
992
993    LOG_FUNCTION_NAME;
994
995    imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
996
997    if ( OMX_StateExecuting != mComponentState )
998        {
999        CAMHAL_LOGEA("OMX component is not in executing state");
1000        ret = -EINVAL;
1001        }
1002
1003        {
1004        android::AutoMutex lock(mBracketingLock);
1005
1006        if ( mBracketingEnabled )
1007            {
1008            return ret;
1009            }
1010        }
1011
1012    if ( 0 == imgCaptureData->mNumBufs )
1013        {
1014        CAMHAL_LOGEB("Image capture buffers set to %d", imgCaptureData->mNumBufs);
1015        ret = -EINVAL;
1016        }
1017
1018    if ( mPending3Asettings )
1019        apply3Asettings(mParameters3A);
1020
1021    if ( NO_ERROR == ret )
1022        {
1023        android::AutoMutex lock(mBracketingLock);
1024
1025        mBracketingRange = range;
1026        mBracketingBuffersQueued = new bool[imgCaptureData->mNumBufs];
1027        if ( NULL == mBracketingBuffersQueued )
1028            {
1029            CAMHAL_LOGEA("Unable to allocate bracketing management structures");
1030            ret = -1;
1031            }
1032
1033        if ( NO_ERROR == ret )
1034            {
1035            mBracketingBuffersQueuedCount = imgCaptureData->mNumBufs;
1036            mBurstFramesAccum = imgCaptureData->mNumBufs;
1037            mLastBracetingBufferIdx = mBracketingBuffersQueuedCount - 1;
1038
1039            for ( int i = 0 ; i  < imgCaptureData->mNumBufs ; i++ )
1040                {
1041                mBracketingBuffersQueued[i] = true;
1042                }
1043
1044            }
1045        }
1046
1047    if ( NO_ERROR == ret )
1048        {
1049        CachedCaptureParameters* cap_params = cacheCaptureParameters();
1050        ret = startImageCapture(true, cap_params);
1051        delete cap_params;
1052            {
1053            android::AutoMutex lock(mBracketingLock);
1054
1055            if ( NO_ERROR == ret )
1056                {
1057                mBracketingEnabled = true;
1058                }
1059            else
1060                {
1061                mBracketingEnabled = false;
1062                }
1063            }
1064        }
1065
1066    LOG_FUNCTION_NAME_EXIT;
1067
1068    return ret;
1069}
1070
1071status_t OMXCameraAdapter::stopBracketing()
1072{
1073  status_t ret = NO_ERROR;
1074
1075    LOG_FUNCTION_NAME;
1076
1077    ret = stopImageCapture();
1078
1079    android::AutoMutex lock(mBracketingLock);
1080
1081    if ( NULL != mBracketingBuffersQueued )
1082    {
1083        delete [] mBracketingBuffersQueued;
1084    }
1085
1086    mBracketingBuffersQueued = NULL;
1087    mBracketingEnabled = false;
1088    mBracketingBuffersQueuedCount = 0;
1089    mLastBracetingBufferIdx = 0;
1090
1091    LOG_FUNCTION_NAME_EXIT;
1092
1093    return ret;
1094}
1095
1096status_t OMXCameraAdapter::startImageCapture(bool bracketing, CachedCaptureParameters* capParams)
1097{
1098    status_t ret = NO_ERROR;
1099    OMX_ERRORTYPE eError = OMX_ErrorNone;
1100    OMXCameraPortParameters * capData = NULL;
1101    OMX_CONFIG_BOOLEANTYPE bOMX;
1102    size_t bracketingSent = 0;
1103
1104    LOG_FUNCTION_NAME;
1105
1106    android::AutoMutex lock(mImageCaptureLock);
1107
1108    if(!mCaptureConfigured)
1109        {
1110        ///Image capture was cancelled before we could start
1111        return NO_ERROR;
1112        }
1113
1114    if ( 0 != mStartCaptureSem.Count() )
1115        {
1116        CAMHAL_LOGEB("Error mStartCaptureSem semaphore count %d", mStartCaptureSem.Count());
1117        return NO_INIT;
1118        }
1119
1120    if ( !bracketing ) {
1121        if ((getNextState() & (CAPTURE_ACTIVE|BRACKETING_ACTIVE)) == 0) {
1122            CAMHAL_LOGDA("trying starting capture when already canceled");
1123            return NO_ERROR;
1124        }
1125    }
1126
1127    if (!capParams) {
1128        CAMHAL_LOGE("Invalid cached parameters sent!");
1129        return BAD_VALUE;
1130    }
1131
1132    // Camera framework doesn't expect face callbacks once capture is triggered
1133    pauseFaceDetection(true);
1134
1135    //During bracketing image capture is already active
1136    {
1137    android::AutoMutex lock(mBracketingLock);
1138    if ( mBracketingEnabled )
1139        {
1140        //Stop bracketing, activate normal burst for the remaining images
1141        mBracketingEnabled = false;
1142        ret = sendBracketFrames(bracketingSent);
1143
1144        // Check if we accumulated enough buffers
1145        if ( bracketingSent < ( mBracketingRange - 1 ) )
1146            {
1147            mCapturedFrames = mBracketingRange + ( ( mBracketingRange - 1 ) - bracketingSent );
1148            }
1149        else
1150            {
1151            mCapturedFrames = mBracketingRange;
1152            }
1153        mBurstFramesQueued = 0;
1154        mBurstFramesAccum = mCapturedFrames;
1155
1156        if(ret != NO_ERROR)
1157            goto EXIT;
1158        else
1159            return ret;
1160        }
1161    }
1162
1163    if ( NO_ERROR == ret ) {
1164        if (capParams->mPendingCaptureSettings & SetRotation) {
1165            mPendingCaptureSettings &= ~SetRotation;
1166            ret = setPictureRotation(mPictureRotation);
1167            if ( NO_ERROR != ret ) {
1168                CAMHAL_LOGEB("Error configuring image rotation %x", ret);
1169            }
1170        }
1171
1172        if (capParams->mPendingCaptureSettings & SetBurstExpBracket) {
1173            mPendingCaptureSettings &= ~SetBurstExpBracket;
1174            if ( mBracketingSet ) {
1175                ret = doExposureBracketing(capParams->mExposureBracketingValues,
1176                                            capParams->mExposureGainBracketingValues,
1177                                            capParams->mExposureGainBracketingModes,
1178                                            0,
1179                                            0,
1180                                            capParams->mFlushShotConfigQueue,
1181                                            capParams->mExposureBracketMode);
1182            } else {
1183                ret = doExposureBracketing(capParams->mExposureBracketingValues,
1184                                    capParams->mExposureGainBracketingValues,
1185                                    capParams->mExposureGainBracketingModes,
1186                                    capParams->mExposureBracketingValidEntries,
1187                                    capParams->mBurstFrames,
1188                                    capParams->mFlushShotConfigQueue,
1189                                    capParams->mExposureBracketMode);
1190            }
1191
1192            if ( ret != NO_ERROR ) {
1193                CAMHAL_LOGEB("setExposureBracketing() failed %d", ret);
1194                goto EXIT;
1195            }
1196        }
1197    }
1198
1199#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
1200            CameraHal::PPM("startImageCapture bracketing configs done: ", &mStartCapture);
1201#endif
1202
1203    capData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
1204
1205    //OMX shutter callback events are only available in hq mode
1206    if ( (HIGH_QUALITY == mCapMode) || (HIGH_QUALITY_ZSL== mCapMode)) {
1207        if ( NO_ERROR == ret )
1208            {
1209            ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
1210                                        (OMX_EVENTTYPE) OMX_EventIndexSettingChanged,
1211                                        OMX_ALL,
1212                                        OMX_TI_IndexConfigShutterCallback,
1213                                        mStartCaptureSem);
1214            }
1215
1216        if ( NO_ERROR == ret )
1217            {
1218            ret = setShutterCallback(true);
1219            }
1220
1221    }
1222
1223    if (mPending3Asettings) {
1224        apply3Asettings(mParameters3A);
1225    }
1226
1227    if (ret == NO_ERROR) {
1228        int index = 0;
1229        int queued = 0;
1230        android::AutoMutex lock(mBurstLock);
1231
1232        if (capParams->mFlushShotConfigQueue) {
1233            // reset shot queue
1234            mCapturedFrames = mBurstFrames;
1235            mBurstFramesAccum = mBurstFrames;
1236            mBurstFramesQueued = 0;
1237            for ( int index = 0 ; index < capData->mNumBufs ; index++ ) {
1238                if (OMXCameraPortParameters::FILL == capData->mStatus[index]) {
1239                    mBurstFramesQueued++;
1240                }
1241            }
1242        } else {
1243            mCapturedFrames += mBurstFrames;
1244            mBurstFramesAccum += mBurstFrames;
1245        }
1246        CAMHAL_LOGD("mBurstFramesQueued = %d mBurstFramesAccum = %d index = %d "
1247                    "capData->mNumBufs = %d queued = %d capData->mMaxQueueable = %d",
1248                    mBurstFramesQueued,mBurstFramesAccum,index,
1249                    capData->mNumBufs,queued,capData->mMaxQueueable);
1250        CAMHAL_LOGD("%d", (mBurstFramesQueued < mBurstFramesAccum)
1251                          && (index < capData->mNumBufs)
1252                          && (queued < capData->mMaxQueueable));
1253        while ((mBurstFramesQueued < mBurstFramesAccum) &&
1254               (index < capData->mNumBufs) &&
1255               (queued < capData->mMaxQueueable)) {
1256            if (capData->mStatus[index] == OMXCameraPortParameters::IDLE) {
1257                CAMHAL_LOGDB("Queuing buffer on Capture port - %p",
1258                             capData->mBufferHeader[index]->pBuffer);
1259                capData->mStatus[index] = OMXCameraPortParameters::FILL;
1260                eError = OMX_FillThisBuffer(mCameraAdapterParameters.mHandleComp,
1261                            (OMX_BUFFERHEADERTYPE*)capData->mBufferHeader[index]);
1262                GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1263                mBurstFramesQueued++;
1264                queued++;
1265            } else if (OMXCameraPortParameters::FILL == capData->mStatus[index]) {
1266               CAMHAL_LOGE("Not queueing index = %d", index);
1267                queued++;
1268            }
1269            index++;
1270        }
1271
1272#ifdef CAMERAHAL_USE_RAW_IMAGE_SAVING
1273        if (mRawCapture) {
1274            capData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoPortIndex];
1275
1276            ///Queue all the buffers on capture port
1277            for ( int index = 0 ; index < capData->mNumBufs ; index++ ) {
1278                CAMHAL_LOGDB("Queuing buffer on Video port (for RAW capture) - 0x%x", ( unsigned int ) capData->mBufferHeader[index]->pBuffer);
1279                capData->mStatus[index] = OMXCameraPortParameters::FILL;
1280                eError = OMX_FillThisBuffer(mCameraAdapterParameters.mHandleComp,
1281                        (OMX_BUFFERHEADERTYPE*)capData->mBufferHeader[index]);
1282
1283                GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1284            }
1285        }
1286#endif
1287
1288        mWaitingForSnapshot = true;
1289        mCaptureSignalled = false;
1290
1291        // Capturing command is not needed when capturing in video mode
1292        // Only need to queue buffers on image ports
1293        if ( ( mCapMode != VIDEO_MODE ) && ( mCapMode != VIDEO_MODE_HQ ) ) {
1294            OMX_INIT_STRUCT_PTR (&bOMX, OMX_CONFIG_BOOLEANTYPE);
1295            bOMX.bEnabled = OMX_TRUE;
1296
1297            /// sending Capturing Command to the component
1298            eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
1299                                   OMX_IndexConfigCapturing,
1300                                   &bOMX);
1301
1302            CAMHAL_LOGDB("Capture set - 0x%x", eError);
1303
1304            GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1305        }
1306    }
1307
1308#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
1309            CameraHal::PPM("startImageCapture image buffers queued and capture enabled: ", &mStartCapture);
1310#endif
1311
1312    //OMX shutter callback events are only available in hq mode
1313
1314    if ( (HIGH_QUALITY == mCapMode) || (HIGH_QUALITY_ZSL== mCapMode))
1315        {
1316        if ( NO_ERROR == ret )
1317            {
1318            ret = mStartCaptureSem.WaitTimeout(OMX_CAPTURE_TIMEOUT);
1319            }
1320
1321        //If something bad happened while we wait
1322        if (mComponentState != OMX_StateExecuting)
1323          {
1324            CAMHAL_LOGEA("Invalid State after Image Capture Exitting!!!");
1325            goto EXIT;
1326          }
1327
1328        if ( NO_ERROR == ret )
1329            {
1330            CAMHAL_LOGDA("Shutter callback received");
1331            notifyShutterSubscribers();
1332            }
1333        else
1334            {
1335            ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
1336                               (OMX_EVENTTYPE) OMX_EventIndexSettingChanged,
1337                               OMX_ALL,
1338                               OMX_TI_IndexConfigShutterCallback,
1339                               NULL);
1340            CAMHAL_LOGEA("Timeout expired on shutter callback");
1341            goto EXIT;
1342            }
1343
1344        }
1345
1346#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
1347            CameraHal::PPM("startImageCapture shutter event received: ", &mStartCapture);
1348#endif
1349
1350    return (ret | Utils::ErrorUtils::omxToAndroidError(eError));
1351
1352EXIT:
1353    CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
1354    mWaitingForSnapshot = false;
1355    mCaptureSignalled = false;
1356    performCleanupAfterError();
1357    LOG_FUNCTION_NAME_EXIT;
1358    return (ret | Utils::ErrorUtils::omxToAndroidError(eError));
1359}
1360
1361status_t OMXCameraAdapter::stopImageCapture()
1362{
1363    status_t ret = NO_ERROR;
1364    OMX_ERRORTYPE eError = OMX_ErrorNone;
1365    OMX_CONFIG_BOOLEANTYPE bOMX;
1366    OMXCameraPortParameters *imgCaptureData = NULL;
1367
1368    LOG_FUNCTION_NAME;
1369
1370    android::AutoMutex lock(mImageCaptureLock);
1371
1372    if (!mCaptureConfigured) {
1373        //Capture is not ongoing, return from here
1374        return NO_ERROR;
1375    }
1376
1377    if ( 0 != mStopCaptureSem.Count() ) {
1378        CAMHAL_LOGEB("Error mStopCaptureSem semaphore count %d", mStopCaptureSem.Count());
1379        goto EXIT;
1380    }
1381
1382    // TODO(XXX): Reprocessing is currently piggy-backing capture commands
1383    if (mAdapterState == REPROCESS_STATE) {
1384        ret = stopReprocess();
1385    }
1386
1387    //Disable the callback first
1388    mWaitingForSnapshot = false;
1389
1390    // OMX shutter callback events are only available in hq mode
1391    if ((HIGH_QUALITY == mCapMode) || (HIGH_QUALITY_ZSL== mCapMode)) {
1392        //Disable the callback first
1393        ret = setShutterCallback(false);
1394
1395        // if anybody is waiting on the shutter callback
1396        // signal them and then recreate the semaphore
1397        if ( 0 != mStartCaptureSem.Count() ) {
1398
1399            for (int i = mStartCaptureSem.Count(); i < 0; i++) {
1400            ret |= SignalEvent(mCameraAdapterParameters.mHandleComp,
1401                               (OMX_EVENTTYPE) OMX_EventIndexSettingChanged,
1402                               OMX_ALL,
1403                               OMX_TI_IndexConfigShutterCallback,
1404                               NULL );
1405            }
1406            mStartCaptureSem.Create(0);
1407        }
1408    } else if (CP_CAM == mCapMode) {
1409        // Reset shot config queue
1410        OMX_TI_CONFIG_ENQUEUESHOTCONFIGS resetShotConfigs;
1411        OMX_INIT_STRUCT_PTR(&resetShotConfigs, OMX_TI_CONFIG_ENQUEUESHOTCONFIGS);
1412
1413        resetShotConfigs.nPortIndex = mCameraAdapterParameters.mImagePortIndex;
1414        resetShotConfigs.bFlushQueue = OMX_TRUE;
1415        resetShotConfigs.nNumConfigs = 0;
1416        eError =  OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
1417                        ( OMX_INDEXTYPE ) OMX_TI_IndexConfigEnqueueShotConfigs,
1418                            &resetShotConfigs);
1419        if ( OMX_ErrorNone != eError ) {
1420            CAMHAL_LOGEB("Error while reset shot config 0x%x", eError);
1421            goto EXIT;
1422        } else {
1423            CAMHAL_LOGDA("Shot config reset successfully");
1424        }
1425    }
1426
1427    //Wait here for the capture to be done, in worst case timeout and proceed with cleanup
1428    mCaptureSem.WaitTimeout(OMX_CAPTURE_TIMEOUT);
1429
1430    //If somethiing bad happened while we wait
1431    if (mComponentState == OMX_StateInvalid)
1432      {
1433        CAMHAL_LOGEA("Invalid State Image Capture Stop Exitting!!!");
1434        goto EXIT;
1435      }
1436
1437    // Disable image capture
1438    // Capturing command is not needed when capturing in video mode
1439    if ( ( mCapMode != VIDEO_MODE ) && ( mCapMode != VIDEO_MODE_HQ ) ) {
1440        OMX_INIT_STRUCT_PTR (&bOMX, OMX_CONFIG_BOOLEANTYPE);
1441        bOMX.bEnabled = OMX_FALSE;
1442        imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
1443        eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
1444                               OMX_IndexConfigCapturing,
1445                               &bOMX);
1446        if ( OMX_ErrorNone != eError ) {
1447            CAMHAL_LOGDB("Error during SetConfig- 0x%x", eError);
1448            ret = -1;
1449            goto EXIT;
1450        }
1451    }
1452
1453    CAMHAL_LOGDB("Capture set - 0x%x", eError);
1454
1455    mCaptureSignalled = true; //set this to true if we exited because of timeout
1456
1457    {
1458        android::AutoMutex lock(mFrameCountMutex);
1459        mFrameCount = 0;
1460        mFirstFrameCondition.broadcast();
1461    }
1462
1463    // Stop is always signalled externally in CPCAM mode
1464    // We need to make sure we really stop
1465    if ((mCapMode == CP_CAM)) {
1466        disableReprocess();
1467        disableImagePort();
1468        if ( NULL != mReleaseImageBuffersCallback ) {
1469            mReleaseImageBuffersCallback(mReleaseData);
1470        }
1471    }
1472
1473    // Moving code for below commit here as an optimization for continuous capture,
1474    // so focus settings don't have to reapplied after each capture
1475    // c78fa2a CameraHAL: Always reset focus mode after capture
1476    // Workaround when doing many consecutive shots, CAF wasn't getting restarted.
1477    mPending3Asettings |= SetFocus;
1478
1479    mCapturedFrames = 0;
1480    mBurstFramesAccum = 0;
1481    mBurstFramesQueued = 0;
1482
1483    return (ret | Utils::ErrorUtils::omxToAndroidError(eError));
1484
1485EXIT:
1486    CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
1487    //Release image buffers
1488    if ( NULL != mReleaseImageBuffersCallback ) {
1489        mReleaseImageBuffersCallback(mReleaseData);
1490    }
1491
1492    {
1493        android::AutoMutex lock(mFrameCountMutex);
1494        mFrameCount = 0;
1495        mFirstFrameCondition.broadcast();
1496    }
1497
1498    performCleanupAfterError();
1499    LOG_FUNCTION_NAME_EXIT;
1500    return (ret | Utils::ErrorUtils::omxToAndroidError(eError));
1501}
1502
1503status_t OMXCameraAdapter::disableImagePort(){
1504    status_t ret = NO_ERROR;
1505    OMX_ERRORTYPE eError = OMX_ErrorNone;
1506    OMXCameraPortParameters *imgCaptureData = NULL;
1507    OMXCameraPortParameters *imgRawCaptureData = NULL;
1508
1509    if (!mCaptureConfigured) {
1510        return NO_ERROR;
1511    }
1512
1513    mCaptureConfigured = false;
1514    imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
1515    imgRawCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoPortIndex]; // for RAW capture
1516
1517    ///Register for Image port Disable event
1518    ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
1519                                OMX_EventCmdComplete,
1520                                OMX_CommandPortDisable,
1521                                mCameraAdapterParameters.mImagePortIndex,
1522                                mStopCaptureSem);
1523    ///Disable Capture Port
1524    eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
1525                                OMX_CommandPortDisable,
1526                                mCameraAdapterParameters.mImagePortIndex,
1527                                NULL);
1528
1529    ///Free all the buffers on capture port
1530    if (imgCaptureData) {
1531        CAMHAL_LOGDB("Freeing buffer on Capture port - %d", imgCaptureData->mNumBufs);
1532        for ( int index = 0 ; index < imgCaptureData->mNumBufs ; index++) {
1533            CAMHAL_LOGDB("Freeing buffer on Capture port - 0x%x",
1534                         ( unsigned int ) imgCaptureData->mBufferHeader[index]->pBuffer);
1535            eError = OMX_FreeBuffer(mCameraAdapterParameters.mHandleComp,
1536                                    mCameraAdapterParameters.mImagePortIndex,
1537                                    (OMX_BUFFERHEADERTYPE*)imgCaptureData->mBufferHeader[index]);
1538
1539            GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1540        }
1541    }
1542    CAMHAL_LOGDA("Waiting for port disable");
1543    //Wait for the image port enable event
1544    ret = mStopCaptureSem.WaitTimeout(OMX_CMD_TIMEOUT);
1545
1546    //If somethiing bad happened while we wait
1547    if (mComponentState == OMX_StateInvalid)
1548      {
1549        CAMHAL_LOGEA("Invalid State after Disable Image Port Exitting!!!");
1550        goto EXIT;
1551      }
1552
1553    if ( NO_ERROR == ret ) {
1554        CAMHAL_LOGDA("Port disabled");
1555    } else {
1556        ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
1557                           OMX_EventCmdComplete,
1558                           OMX_CommandPortDisable,
1559                           mCameraAdapterParameters.mImagePortIndex,
1560                           NULL);
1561        CAMHAL_LOGDA("Timeout expired on port disable");
1562        goto EXIT;
1563    }
1564
1565    deinitInternalBuffers(mCameraAdapterParameters.mImagePortIndex);
1566
1567    // since port settings are not persistent after port is disabled...
1568    mPendingCaptureSettings |= SetFormat;
1569
1570#ifdef CAMERAHAL_USE_RAW_IMAGE_SAVING
1571
1572    if (mRawCapture) {
1573        ///Register for Video port Disable event
1574        ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
1575                OMX_EventCmdComplete,
1576                OMX_CommandPortDisable,
1577                mCameraAdapterParameters.mVideoPortIndex,
1578                mStopCaptureSem);
1579        ///Disable RawCapture Port
1580        eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
1581                OMX_CommandPortDisable,
1582                mCameraAdapterParameters.mVideoPortIndex,
1583                NULL);
1584
1585        GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1586
1587        ///Free all the buffers on RawCapture port
1588        if (imgRawCaptureData) {
1589            CAMHAL_LOGDB("Freeing buffer on Capture port - %d", imgRawCaptureData->mNumBufs);
1590            for ( int index = 0 ; index < imgRawCaptureData->mNumBufs ; index++) {
1591                CAMHAL_LOGDB("Freeing buffer on Capture port - 0x%x", ( unsigned int ) imgRawCaptureData->mBufferHeader[index]->pBuffer);
1592                eError = OMX_FreeBuffer(mCameraAdapterParameters.mHandleComp,
1593                        mCameraAdapterParameters.mVideoPortIndex,
1594                        (OMX_BUFFERHEADERTYPE*)imgRawCaptureData->mBufferHeader[index]);
1595
1596                GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1597            }
1598        }
1599        CAMHAL_LOGDA("Waiting for Video port disable");
1600        //Wait for the image port enable event
1601        mStopCaptureSem.WaitTimeout(OMX_CMD_TIMEOUT);
1602        CAMHAL_LOGDA("Video Port disabled");
1603    }
1604#endif
1605
1606EXIT:
1607    return (ret | Utils::ErrorUtils::omxToAndroidError(eError));
1608}
1609
1610status_t OMXCameraAdapter::initInternalBuffers(OMX_U32 portIndex)
1611{
1612    OMX_ERRORTYPE eError = OMX_ErrorNone;
1613    int index = 0;
1614    OMX_TI_PARAM_USEBUFFERDESCRIPTOR bufferdesc;
1615
1616    /* Indicate to Ducati that we're planning to use dynamically-mapped buffers */
1617    OMX_INIT_STRUCT_PTR (&bufferdesc, OMX_TI_PARAM_USEBUFFERDESCRIPTOR);
1618    bufferdesc.nPortIndex = portIndex;
1619    bufferdesc.bEnabled = OMX_FALSE;
1620    bufferdesc.eBufferType = OMX_TI_BufferTypePhysicalPageList;
1621
1622    eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp,
1623            (OMX_INDEXTYPE) OMX_TI_IndexUseBufferDescriptor,
1624            &bufferdesc);
1625    if (eError!=OMX_ErrorNone) {
1626        CAMHAL_LOGEB("OMX_SetParameter - %x", eError);
1627        return -EINVAL;
1628    }
1629
1630    CAMHAL_LOGDA("Initializing internal buffers");
1631    do {
1632        OMX_TI_PARAM_COMPONENTBUFALLOCTYPE bufferalloc;
1633        OMX_TI_PARAM_COMPONENTBUFALLOCTYPE bufferallocset;
1634        OMX_INIT_STRUCT_PTR (&bufferalloc, OMX_TI_PARAM_COMPONENTBUFALLOCTYPE);
1635        bufferalloc.nPortIndex = portIndex;
1636        bufferalloc.nIndex = index;
1637
1638        eError = OMX_GetParameter (mCameraAdapterParameters.mHandleComp,
1639                (OMX_INDEXTYPE)OMX_TI_IndexParamComponentBufferAllocation,
1640                &bufferalloc);
1641        if (eError == OMX_ErrorNoMore) {
1642            return NO_ERROR;
1643        }
1644        if (eError != OMX_ErrorNone) {
1645            CAMHAL_LOGE("GetParameter failed error = 0x%x", eError);
1646            break;
1647        }
1648
1649        CAMHAL_LOGDB("Requesting buftype %d of size %dx%d",
1650            (int)bufferalloc.eBufType, (int)bufferalloc.nAllocWidth,
1651            (int)bufferalloc.nAllocLines);
1652
1653        bufferalloc.eBufType = OMX_TI_BufferTypeHardwareReserved1D;
1654
1655        OMX_INIT_STRUCT_PTR (&bufferallocset, OMX_TI_PARAM_COMPONENTBUFALLOCTYPE);
1656        bufferallocset.nPortIndex = portIndex;
1657        bufferallocset.nIndex = index;
1658        bufferallocset.eBufType = OMX_TI_BufferTypeHardwareReserved1D;
1659        bufferallocset.nAllocWidth = bufferalloc.nAllocWidth;
1660        bufferallocset.nAllocLines = bufferalloc.nAllocLines;
1661
1662        eError = OMX_SetParameter (mCameraAdapterParameters.mHandleComp,
1663                (OMX_INDEXTYPE)OMX_TI_IndexParamComponentBufferAllocation,
1664                &bufferallocset);
1665        if (eError != OMX_ErrorNone) {
1666            CAMHAL_LOGE("SetParameter failed, error=%08x", eError);
1667            if (eError == OMX_ErrorNoMore) return NO_ERROR;
1668            break;
1669        }
1670
1671        index++;
1672
1673        /* 1 is an arbitrary limit */
1674    } while (index < 1);
1675
1676    CAMHAL_LOGV("Ducati requested too many (>1) internal buffers");
1677
1678    return -EINVAL;
1679}
1680
1681status_t OMXCameraAdapter::deinitInternalBuffers(OMX_U32 portIndex)
1682{
1683    OMX_ERRORTYPE eError = OMX_ErrorNone;
1684    OMX_TI_PARAM_USEBUFFERDESCRIPTOR bufferdesc;
1685
1686    OMX_INIT_STRUCT_PTR (&bufferdesc, OMX_TI_PARAM_USEBUFFERDESCRIPTOR);
1687    bufferdesc.nPortIndex = portIndex;
1688    bufferdesc.bEnabled = OMX_FALSE;
1689    bufferdesc.eBufferType = OMX_TI_BufferTypeDefault;
1690
1691    eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp,
1692            (OMX_INDEXTYPE) OMX_TI_IndexUseBufferDescriptor,
1693            &bufferdesc);
1694    if (eError!=OMX_ErrorNone) {
1695        CAMHAL_LOGEB("OMX_SetParameter - %x", eError);
1696        return -EINVAL;
1697    }
1698
1699    OMX_TI_PARAM_COMPONENTBUFALLOCTYPE bufferalloc;
1700    OMX_INIT_STRUCT_PTR (&bufferalloc, OMX_TI_PARAM_COMPONENTBUFALLOCTYPE);
1701    bufferalloc.nPortIndex = portIndex;
1702    bufferalloc.eBufType = OMX_TI_BufferTypeDefault;
1703    bufferalloc.nAllocWidth = 1;
1704    bufferalloc.nAllocLines = 1;
1705    eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp,
1706            (OMX_INDEXTYPE) OMX_TI_IndexParamComponentBufferAllocation,
1707            &bufferalloc);
1708    if (eError!=OMX_ErrorNone) {
1709        CAMHAL_LOGEB("OMX_SetParameter - %x", eError);
1710        return -EINVAL;
1711    }
1712
1713    return Utils::ErrorUtils::omxToAndroidError(eError);
1714}
1715
1716status_t OMXCameraAdapter::UseBuffersCapture(CameraBuffer * bufArr, int num)
1717{
1718    LOG_FUNCTION_NAME;
1719
1720    status_t ret = NO_ERROR;
1721    OMX_ERRORTYPE eError = OMX_ErrorNone;
1722    OMXCameraPortParameters * imgCaptureData = NULL;
1723    OMXCameraPortParameters cap;
1724
1725    imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
1726
1727    if ( 0 != mUseCaptureSem.Count() )
1728        {
1729        CAMHAL_LOGEB("Error mUseCaptureSem semaphore count %d", mUseCaptureSem.Count());
1730        return BAD_VALUE;
1731        }
1732
1733    CAMHAL_ASSERT(num > 0);
1734
1735    // if some setting that requires a SetParameter (including
1736    // changing buffer types) then we need to disable the port
1737    // before being allowed to apply the settings
1738    if ((mPendingCaptureSettings & ECaptureParamSettings) ||
1739            bufArr[0].type != imgCaptureData->mBufferType ||
1740            imgCaptureData->mNumBufs != num) {
1741        if (mCaptureConfigured) {
1742            disableImagePort();
1743            if ( NULL != mReleaseImageBuffersCallback ) {
1744                mReleaseImageBuffersCallback(mReleaseData);
1745            }
1746        }
1747
1748        imgCaptureData->mBufferType = bufArr[0].type;
1749        imgCaptureData->mNumBufs = num;
1750
1751        CAMHAL_LOGDB("Params Width = %d", (int)imgCaptureData->mWidth);
1752        CAMHAL_LOGDB("Params Height = %d", (int)imgCaptureData->mHeight);
1753
1754        if (mPendingCaptureSettings & SetFormat) {
1755            mPendingCaptureSettings &= ~SetFormat;
1756            ret = setFormat(OMX_CAMERA_PORT_IMAGE_OUT_IMAGE, *imgCaptureData);
1757            if ( ret != NO_ERROR ) {
1758                CAMHAL_LOGEB("setFormat() failed %d", ret);
1759                LOG_FUNCTION_NAME_EXIT;
1760                return ret;
1761            }
1762        }
1763
1764        if (mPendingCaptureSettings & SetThumb) {
1765            mPendingCaptureSettings &= ~SetThumb;
1766            ret = setThumbnailParams(mThumbWidth, mThumbHeight, mThumbQuality);
1767            if ( NO_ERROR != ret) {
1768                CAMHAL_LOGEB("Error configuring thumbnail size %x", ret);
1769                return ret;
1770            }
1771        }
1772
1773        if (mPendingCaptureSettings & SetQuality) {
1774            mPendingCaptureSettings &= ~SetQuality;
1775            ret = setImageQuality(mPictureQuality);
1776            if ( NO_ERROR != ret) {
1777                CAMHAL_LOGEB("Error configuring image quality %x", ret);
1778                goto EXIT;
1779            }
1780        }
1781
1782        // Configure DOMX to use either gralloc handles or vptrs
1783        {
1784            OMX_TI_PARAMUSENATIVEBUFFER domxUseGrallocHandles;
1785            OMX_INIT_STRUCT_PTR (&domxUseGrallocHandles, OMX_TI_PARAMUSENATIVEBUFFER);
1786
1787            domxUseGrallocHandles.nPortIndex = mCameraAdapterParameters.mImagePortIndex;
1788            if (bufArr[0].type == CAMERA_BUFFER_ANW) {
1789                CAMHAL_LOGD ("Using ANW Buffers");
1790                initInternalBuffers(mCameraAdapterParameters.mImagePortIndex);
1791                domxUseGrallocHandles.bEnable = OMX_TRUE;
1792            } else {
1793                CAMHAL_LOGD ("Using ION Buffers");
1794                domxUseGrallocHandles.bEnable = OMX_FALSE;
1795            }
1796
1797            eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp,
1798                                    (OMX_INDEXTYPE)OMX_TI_IndexUseNativeBuffers, &domxUseGrallocHandles);
1799            if (eError!=OMX_ErrorNone) {
1800                CAMHAL_LOGEB("OMX_SetParameter - %x", eError);
1801            }
1802            GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1803        }
1804
1805#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
1806
1807    CameraHal::PPM("Takepicture image port configuration: ", &bufArr->ppmStamp);
1808
1809#endif
1810
1811        // Register for Image port ENABLE event
1812        ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
1813                               OMX_EventCmdComplete,
1814                               OMX_CommandPortEnable,
1815                               mCameraAdapterParameters.mImagePortIndex,
1816                               mUseCaptureSem);
1817
1818        // Enable Capture Port
1819        eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
1820                                 OMX_CommandPortEnable,
1821                                 mCameraAdapterParameters.mImagePortIndex,
1822                                 NULL);
1823
1824        CAMHAL_LOGDB("OMX_UseBuffer = 0x%x", eError);
1825        GOTO_EXIT_IF(( eError != OMX_ErrorNone ), eError);
1826
1827        for (int index = 0 ; index < imgCaptureData->mNumBufs ; index++) {
1828            OMX_BUFFERHEADERTYPE *pBufferHdr;
1829            CAMHAL_LOGDB("OMX_UseBuffer Capture address: 0x%x, size = %d",
1830                         (unsigned int)bufArr[index].opaque,
1831                         (int)imgCaptureData->mBufSize);
1832
1833            eError = OMX_UseBuffer(mCameraAdapterParameters.mHandleComp,
1834                                   &pBufferHdr,
1835                                   mCameraAdapterParameters.mImagePortIndex,
1836                                   0,
1837                                   imgCaptureData->mBufSize,
1838                                   (OMX_U8*)camera_buffer_get_omx_ptr(&bufArr[index]));
1839
1840            CAMHAL_LOGDB("OMX_UseBuffer = 0x%x", eError);
1841            GOTO_EXIT_IF(( eError != OMX_ErrorNone ), eError);
1842
1843            pBufferHdr->pAppPrivate = (OMX_PTR) &bufArr[index];
1844            bufArr[index].index = index;
1845            pBufferHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
1846            pBufferHdr->nVersion.s.nVersionMajor = 1 ;
1847            pBufferHdr->nVersion.s.nVersionMinor = 1 ;
1848            pBufferHdr->nVersion.s.nRevision = 0;
1849            pBufferHdr->nVersion.s.nStep =  0;
1850            imgCaptureData->mBufferHeader[index] = pBufferHdr;
1851            imgCaptureData->mStatus[index] = OMXCameraPortParameters::IDLE;
1852        }
1853
1854        // Wait for the image port enable event
1855        CAMHAL_LOGDA("Waiting for port enable");
1856        ret = mUseCaptureSem.WaitTimeout(OMX_CMD_TIMEOUT);
1857
1858        // If somethiing bad happened while we wait
1859        if (mComponentState == OMX_StateInvalid) {
1860            CAMHAL_LOGEA("Invalid State after Enable Image Port Exitting!!!");
1861            goto EXIT;
1862          }
1863
1864        if (ret != NO_ERROR) {
1865            ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
1866                               OMX_EventCmdComplete,
1867                               OMX_CommandPortEnable,
1868                               mCameraAdapterParameters.mImagePortIndex,
1869                               NULL);
1870            CAMHAL_LOGDA("Timeout expired on port enable");
1871            goto EXIT;
1872        }
1873        CAMHAL_LOGDA("Port enabled");
1874
1875#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
1876
1877    CameraHal::PPM("Takepicture image port enabled and buffers registered: ", &bufArr->ppmStamp);
1878
1879#endif
1880
1881        if (mNextState != LOADED_REPROCESS_CAPTURE_STATE) {
1882            // Enable WB and vector shot extra data for metadata
1883            setExtraData(true, mCameraAdapterParameters.mImagePortIndex, OMX_WhiteBalance);
1884            setExtraData(true, mCameraAdapterParameters.mImagePortIndex, OMX_TI_LSCTable);
1885        }
1886
1887        // CPCam mode only supports vector shot
1888        // Regular capture is not supported
1889        if ( (mCapMode == CP_CAM) && (mNextState != LOADED_REPROCESS_CAPTURE_STATE) ) {
1890            initVectorShot();
1891        }
1892
1893        mCaptureBuffersAvailable.clear();
1894        for (unsigned int i = 0; i < imgCaptureData->mMaxQueueable; i++ ) {
1895            mCaptureBuffersAvailable.add(&mCaptureBuffers[i], 0);
1896        }
1897
1898        // initial ref count for undeqeueued buffers is 1 since buffer provider
1899        // is still holding on to it
1900        for (unsigned int i = imgCaptureData->mMaxQueueable; i < imgCaptureData->mNumBufs; i++ ) {
1901            mCaptureBuffersAvailable.add(&mCaptureBuffers[i], 1);
1902        }
1903    }
1904
1905    if ( NO_ERROR == ret )
1906        {
1907        ret = setupEXIF();
1908        if ( NO_ERROR != ret )
1909            {
1910            CAMHAL_LOGEB("Error configuring EXIF Buffer %x", ret);
1911            }
1912        }
1913
1914    // Choose proper single preview mode for cp capture (reproc or hs)
1915    if (( NO_ERROR == ret) && (OMXCameraAdapter::CP_CAM == mCapMode)) {
1916        OMX_TI_CONFIG_SINGLEPREVIEWMODETYPE singlePrevMode;
1917        OMX_INIT_STRUCT_PTR (&singlePrevMode, OMX_TI_CONFIG_SINGLEPREVIEWMODETYPE);
1918        if (mNextState == LOADED_CAPTURE_STATE) {
1919            singlePrevMode.eMode = OMX_TI_SinglePreviewMode_ImageCaptureHighSpeed;
1920        } else if (mNextState == LOADED_REPROCESS_CAPTURE_STATE) {
1921            singlePrevMode.eMode = OMX_TI_SinglePreviewMode_Reprocess;
1922        } else {
1923            CAMHAL_LOGE("Wrong state trying to start a capture in CPCAM mode?");
1924            singlePrevMode.eMode = OMX_TI_SinglePreviewMode_ImageCaptureHighSpeed;
1925        }
1926        eError =  OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
1927                                (OMX_INDEXTYPE) OMX_TI_IndexConfigSinglePreviewMode,
1928                                &singlePrevMode);
1929        if ( OMX_ErrorNone != eError ) {
1930            CAMHAL_LOGEB("Error while configuring single preview mode 0x%x", eError);
1931            ret = Utils::ErrorUtils::omxToAndroidError(eError);
1932        } else {
1933            CAMHAL_LOGDA("single preview mode configured successfully");
1934        }
1935    }
1936
1937#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
1938
1939    CameraHal::PPM("Takepicture extra configs on image port done: ", &bufArr->ppmStamp);
1940
1941#endif
1942
1943    mCaptureConfigured = true;
1944
1945#ifdef CAMERAHAL_USE_RAW_IMAGE_SAVING
1946    if (mRawCapture) {
1947        mCaptureConfigured = false;
1948    }
1949#endif
1950
1951    return (ret | Utils::ErrorUtils::omxToAndroidError(eError));
1952
1953EXIT:
1954    CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
1955    setExtraData(false, mCameraAdapterParameters.mImagePortIndex, OMX_WhiteBalance);
1956    // TODO: WA: if domx client disables VectShotInfo metadata on the image port, this causes
1957    // VectShotInfo to be disabled internally on preview port also. Remove setting in OMXCapture
1958    // setExtraData(false, mCameraAdapterParameters.mImagePortIndex, OMX_TI_VectShotInfo);
1959    setExtraData(false, mCameraAdapterParameters.mImagePortIndex, OMX_TI_LSCTable);
1960    //Release image buffers
1961    if ( NULL != mReleaseImageBuffersCallback ) {
1962        mReleaseImageBuffersCallback(mReleaseData);
1963    }
1964    performCleanupAfterError();
1965    LOG_FUNCTION_NAME_EXIT;
1966    return (ret | Utils::ErrorUtils::omxToAndroidError(eError));
1967
1968}
1969status_t OMXCameraAdapter::UseBuffersRawCapture(CameraBuffer *bufArr, int num)
1970{
1971    LOG_FUNCTION_NAME
1972    status_t ret;
1973    OMX_ERRORTYPE eError;
1974    OMXCameraPortParameters * imgRawCaptureData = NULL;
1975    Utils::Semaphore camSem;
1976    OMXCameraPortParameters cap;
1977
1978    imgRawCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoPortIndex];
1979
1980    if (mCaptureConfigured) {
1981        return NO_ERROR;
1982    }
1983
1984    camSem.Create();
1985
1986    // mWaitingForSnapshot is true only when we're in the process of capturing
1987    if (mWaitingForSnapshot) {
1988        ///Register for Video port Disable event
1989        ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
1990                (OMX_EVENTTYPE) OMX_EventCmdComplete,
1991                OMX_CommandPortDisable,
1992                mCameraAdapterParameters.mVideoPortIndex,
1993                camSem);
1994
1995        ///Disable Capture Port
1996        eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
1997                OMX_CommandPortDisable,
1998                mCameraAdapterParameters.mVideoPortIndex,
1999                NULL);
2000
2001        CAMHAL_LOGDA("Waiting for port disable");
2002        //Wait for the image port enable event
2003        camSem.Wait();
2004        CAMHAL_LOGDA("Port disabled");
2005    }
2006
2007    imgRawCaptureData->mNumBufs = num;
2008
2009    CAMHAL_LOGDB("RAW Max sensor width = %d", (int)imgRawCaptureData->mWidth);
2010    CAMHAL_LOGDB("RAW Max sensor height = %d", (int)imgRawCaptureData->mHeight);
2011
2012    ret = setFormat(OMX_CAMERA_PORT_VIDEO_OUT_VIDEO, *imgRawCaptureData);
2013
2014    if (ret != NO_ERROR) {
2015        CAMHAL_LOGEB("setFormat() failed %d", ret);
2016        LOG_FUNCTION_NAME_EXIT
2017        return ret;
2018    }
2019
2020    ///Register for Video port ENABLE event
2021    ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
2022                                (OMX_EVENTTYPE) OMX_EventCmdComplete,
2023                                OMX_CommandPortEnable,
2024                                mCameraAdapterParameters.mVideoPortIndex,
2025                                camSem);
2026
2027    ///Enable Video Capture Port
2028    eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
2029                                OMX_CommandPortEnable,
2030                                mCameraAdapterParameters.mVideoPortIndex,
2031                                NULL);
2032
2033    mCaptureBuffersLength = (int)imgRawCaptureData->mBufSize;
2034    for ( int index = 0 ; index < imgRawCaptureData->mNumBufs ; index++ ) {
2035        OMX_BUFFERHEADERTYPE *pBufferHdr;
2036        CAMHAL_LOGDB("OMX_UseBuffer rawCapture address: 0x%x, size = %d ",
2037                     (unsigned int)bufArr[index].opaque,
2038                     (int)imgRawCaptureData->mBufSize );
2039
2040        eError = OMX_UseBuffer( mCameraAdapterParameters.mHandleComp,
2041                                &pBufferHdr,
2042                                mCameraAdapterParameters.mVideoPortIndex,
2043                                0,
2044                                mCaptureBuffersLength,
2045                                (OMX_U8*)camera_buffer_get_omx_ptr(&bufArr[index]));
2046        if (eError != OMX_ErrorNone) {
2047            CAMHAL_LOGEB("OMX_UseBuffer = 0x%x", eError);
2048        }
2049
2050        GOTO_EXIT_IF(( eError != OMX_ErrorNone ), eError);
2051
2052        pBufferHdr->pAppPrivate = (OMX_PTR) &bufArr[index];
2053        bufArr[index].index = index;
2054        pBufferHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
2055        pBufferHdr->nVersion.s.nVersionMajor = 1 ;
2056        pBufferHdr->nVersion.s.nVersionMinor = 1 ;
2057        pBufferHdr->nVersion.s.nRevision = 0;
2058        pBufferHdr->nVersion.s.nStep =  0;
2059        imgRawCaptureData->mBufferHeader[index] = pBufferHdr;
2060
2061    }
2062
2063    //Wait for the image port enable event
2064    CAMHAL_LOGDA("Waiting for port enable");
2065    camSem.Wait();
2066    CAMHAL_LOGDA("Port enabled");
2067
2068    if (NO_ERROR == ret) {
2069        ret = setupEXIF();
2070        if ( NO_ERROR != ret ) {
2071            CAMHAL_LOGEB("Error configuring EXIF Buffer %x", ret);
2072        }
2073    }
2074
2075    mCapturedFrames = mBurstFrames;
2076    mBurstFramesQueued = 0;
2077    mCaptureConfigured = true;
2078
2079    EXIT:
2080
2081    if (eError != OMX_ErrorNone) {
2082        if ( NULL != mErrorNotifier )
2083        {
2084            mErrorNotifier->errorNotify(eError);
2085        }
2086    }
2087
2088    LOG_FUNCTION_NAME_EXIT
2089
2090    return ret;
2091}
2092
2093} // namespace Camera
2094} // namespace Ti
2095