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