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 
29 namespace Ti {
30 namespace Camera {
31 
setParametersCapture(const android::CameraParameters & params,BaseCameraAdapter::AdapterState state)32 status_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 
getPictureBufferSize(CameraFrame & frame,size_t bufferCount)357 status_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 
getBracketingValueMode(const char * a,const char * b) const403 int 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 
parseExpRange(const char * rangeStr,int * expRange,int * gainRange,int * expGainModes,size_t count,size_t & validEntries)417 status_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 
doExposureBracketing(int * evValues,int * evValues2,int * evModes2,size_t evCount,size_t frameCount,bool flush,OMX_BRACKETMODETYPE bracketMode)502 status_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 
setVectorStop(bool toPreview)537 status_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 
initVectorShot()569 status_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 
setVectorShot(int * evValues,int * evValues2,int * evModes2,size_t evCount,size_t frameCount,bool flush,OMX_BRACKETMODETYPE bracketMode)625 status_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 
setExposureBracketing(int * evValues,int * evValues2,size_t evCount,size_t frameCount,OMX_BRACKETMODETYPE bracketMode)753 status_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 
setShutterCallback(bool enabled)842 status_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 
doBracketing(OMX_BUFFERHEADERTYPE * pBuffHeader,CameraFrame::FrameType typeOfFrame)895 status_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 
sendBracketFrames(size_t & framesSent)945 status_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 
startBracketing(int range)988 status_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 
stopBracketing()1071 status_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 
startImageCapture(bool bracketing,CachedCaptureParameters * capParams)1096 status_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 
1352 EXIT:
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 
stopImageCapture()1361 status_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 
1485 EXIT:
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 
disableImagePort()1503 status_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 
1606 EXIT:
1607     return (ret | Utils::ErrorUtils::omxToAndroidError(eError));
1608 }
1609 
initInternalBuffers(OMX_U32 portIndex)1610 status_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 
deinitInternalBuffers(OMX_U32 portIndex)1681 status_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 
UseBuffersCapture(CameraBuffer * bufArr,int num)1716 status_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 
1953 EXIT:
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 }
UseBuffersRawCapture(CameraBuffer * bufArr,int num)1969 status_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