OMXCapture.cpp revision ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cf
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 |= SignalEvent(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    //release any 3A locks if locked
861    ret = set3ALock(OMX_FALSE);
862    if(ret!=NO_ERROR)
863      {
864        CAMHAL_LOGEB("Error Releaseing 3A locks%d", ret);
865      }
866
867    // After capture, face detection should be disabled
868    // and application needs to restart face detection
869    stopFaceDetection();
870
871    //Wait here for the capture to be done, in worst case timeout and proceed with cleanup
872    ret = mCaptureSem.WaitTimeout(OMX_CAPTURE_TIMEOUT);
873    if ( NO_ERROR != ret ) {
874        ret |= SignalEvent(mCameraAdapterParameters.mHandleComp,
875                           (OMX_EVENTTYPE) OMX_EventIndexSettingChanged,
876                           OMX_ALL,
877                           OMX_TI_IndexConfigShutterCallback,
878                           NULL);
879        CAMHAL_LOGEA("Timeout expired on shutter callback");
880    }
881
882    //Disable image capture
883    OMX_INIT_STRUCT_PTR (&bOMX, OMX_CONFIG_BOOLEANTYPE);
884    bOMX.bEnabled = OMX_FALSE;
885    imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
886    eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
887                           OMX_IndexConfigCapturing,
888                           &bOMX);
889    if ( OMX_ErrorNone != eError ) {
890        CAMHAL_LOGDB("Error during SetConfig- 0x%x", eError);
891        ret = -1;
892    }
893
894    CAMHAL_LOGDB("Capture set - 0x%x", eError);
895
896    mCaptureSignalled = true; //set this to true if we exited because of timeout
897
898    mCaptureConfigured = false;
899
900    ///Register for Image port Disable event
901    ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
902                                OMX_EventCmdComplete,
903                                OMX_CommandPortDisable,
904                                mCameraAdapterParameters.mImagePortIndex,
905                                mStopCaptureSem);
906    ///Disable Capture Port
907    eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
908                                OMX_CommandPortDisable,
909                                mCameraAdapterParameters.mImagePortIndex,
910                                NULL);
911
912    ///Free all the buffers on capture port
913    if (imgCaptureData) {
914        CAMHAL_LOGDB("Freeing buffer on Capture port - %d", imgCaptureData->mNumBufs);
915        for ( int index = 0 ; index < imgCaptureData->mNumBufs ; index++) {
916            CAMHAL_LOGDB("Freeing buffer on Capture port - 0x%x",
917                         ( unsigned int ) imgCaptureData->mBufferHeader[index]->pBuffer);
918            eError = OMX_FreeBuffer(mCameraAdapterParameters.mHandleComp,
919                                    mCameraAdapterParameters.mImagePortIndex,
920                                    (OMX_BUFFERHEADERTYPE*)imgCaptureData->mBufferHeader[index]);
921
922            GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
923        }
924    }
925    CAMHAL_LOGDA("Waiting for port disable");
926    //Wait for the image port enable event
927    ret = mStopCaptureSem.WaitTimeout(OMX_CMD_TIMEOUT);
928    if ( NO_ERROR == ret ) {
929        CAMHAL_LOGDA("Port disabled");
930    } else {
931        ret |= SignalEvent(mCameraAdapterParameters.mHandleComp,
932                           OMX_EventCmdComplete,
933                           OMX_CommandPortDisable,
934                           mCameraAdapterParameters.mImagePortIndex,
935                           NULL);
936        CAMHAL_LOGDA("Timeout expired on port disable");
937        goto EXIT;
938    }
939
940    EXIT:
941
942    //Release image buffers
943    if ( NULL != mReleaseImageBuffersCallback ) {
944        mReleaseImageBuffersCallback(mReleaseData);
945    }
946
947    LOG_FUNCTION_NAME_EXIT;
948
949    return ret;
950}
951
952status_t OMXCameraAdapter::UseBuffersCapture(void* bufArr, int num)
953{
954    LOG_FUNCTION_NAME;
955
956    status_t ret = NO_ERROR;
957    OMX_ERRORTYPE eError;
958    OMXCameraPortParameters * imgCaptureData = NULL;
959    uint32_t *buffers = (uint32_t*)bufArr;
960    OMXCameraPortParameters cap;
961
962    imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
963
964    if ( 0 != mUseCaptureSem.Count() )
965        {
966        CAMHAL_LOGEB("Error mUseCaptureSem semaphore count %d", mUseCaptureSem.Count());
967        goto EXIT;
968        }
969
970    imgCaptureData->mNumBufs = num;
971
972    //TODO: Support more pixelformats
973
974    CAMHAL_LOGDB("Params Width = %d", (int)imgCaptureData->mWidth);
975    CAMHAL_LOGDB("Params Height = %d", (int)imgCaptureData->mWidth);
976
977    ret = setFormat(OMX_CAMERA_PORT_IMAGE_OUT_IMAGE, *imgCaptureData);
978    if ( ret != NO_ERROR )
979        {
980        CAMHAL_LOGEB("setFormat() failed %d", ret);
981        LOG_FUNCTION_NAME_EXIT;
982        return ret;
983        }
984
985    ret = setThumbnailParams(mThumbWidth, mThumbHeight, mThumbQuality);
986    if ( NO_ERROR != ret)
987        {
988        CAMHAL_LOGEB("Error configuring thumbnail size %x", ret);
989        return ret;
990        }
991
992    ret = setExposureBracketing( mExposureBracketingValues,
993                                 mExposureBracketingValidEntries, mBurstFrames);
994    if ( ret != NO_ERROR )
995        {
996        CAMHAL_LOGEB("setExposureBracketing() failed %d", ret);
997        return ret;
998        }
999
1000    ret = setImageQuality(mPictureQuality);
1001    if ( NO_ERROR != ret)
1002        {
1003        CAMHAL_LOGEB("Error configuring image quality %x", ret);
1004        return ret;
1005        }
1006
1007    ///Register for Image port ENABLE event
1008    ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
1009                           OMX_EventCmdComplete,
1010                           OMX_CommandPortEnable,
1011                           mCameraAdapterParameters.mImagePortIndex,
1012                           mUseCaptureSem);
1013
1014    ///Enable Capture Port
1015    eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
1016                             OMX_CommandPortEnable,
1017                             mCameraAdapterParameters.mImagePortIndex,
1018                             NULL);
1019
1020    for ( int index = 0 ; index < imgCaptureData->mNumBufs ; index++ )
1021    {
1022        OMX_BUFFERHEADERTYPE *pBufferHdr;
1023        CAMHAL_LOGDB("OMX_UseBuffer Capture address: 0x%x, size = %d",
1024                     (unsigned int)buffers[index],
1025                     (int)imgCaptureData->mBufSize);
1026
1027        eError = OMX_UseBuffer(mCameraAdapterParameters.mHandleComp,
1028                               &pBufferHdr,
1029                               mCameraAdapterParameters.mImagePortIndex,
1030                               0,
1031                               mCaptureBuffersLength,
1032                               (OMX_U8*)buffers[index]);
1033
1034        CAMHAL_LOGDB("OMX_UseBuffer = 0x%x", eError);
1035
1036        GOTO_EXIT_IF(( eError != OMX_ErrorNone ), eError);
1037
1038        pBufferHdr->pAppPrivate = (OMX_PTR) index;
1039        pBufferHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
1040        pBufferHdr->nVersion.s.nVersionMajor = 1 ;
1041        pBufferHdr->nVersion.s.nVersionMinor = 1 ;
1042        pBufferHdr->nVersion.s.nRevision = 0;
1043        pBufferHdr->nVersion.s.nStep =  0;
1044        imgCaptureData->mBufferHeader[index] = pBufferHdr;
1045    }
1046
1047    //Wait for the image port enable event
1048    CAMHAL_LOGDA("Waiting for port enable");
1049    ret = mUseCaptureSem.WaitTimeout(OMX_CMD_TIMEOUT);
1050    if ( ret == NO_ERROR )
1051        {
1052        CAMHAL_LOGDA("Port enabled");
1053        }
1054    else
1055        {
1056        ret |= SignalEvent(mCameraAdapterParameters.mHandleComp,
1057                           OMX_EventCmdComplete,
1058                           OMX_CommandPortEnable,
1059                           mCameraAdapterParameters.mImagePortIndex,
1060                           NULL);
1061        CAMHAL_LOGDA("Timeout expired on port enable");
1062        goto EXIT;
1063        }
1064
1065    if ( NO_ERROR == ret )
1066        {
1067        ret = setupEXIF();
1068        if ( NO_ERROR != ret )
1069            {
1070            CAMHAL_LOGEB("Error configuring EXIF Buffer %x", ret);
1071            }
1072        }
1073
1074    mCapturedFrames = mBurstFrames;
1075    mCaptureConfigured = true;
1076
1077    EXIT:
1078
1079    LOG_FUNCTION_NAME_EXIT;
1080
1081    return ret;
1082}
1083
1084};
1085