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