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