1 /*
2 * Copyright (C) Texas Instruments - http://www.ti.com/
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 /**
18 * @file OMXCapture.cpp
19 *
20 * This file contains functionality for handling image capture.
21 *
22 */
23
24 #include "CameraHal.h"
25 #include "OMXCameraAdapter.h"
26 #include "ErrorUtils.h"
27
28
29 namespace Ti {
30 namespace Camera {
31
setParametersCapture(const android::CameraParameters & params,BaseCameraAdapter::AdapterState state)32 status_t OMXCameraAdapter::setParametersCapture(const android::CameraParameters ¶ms,
33 BaseCameraAdapter::AdapterState state)
34 {
35 status_t ret = NO_ERROR;
36 const char *str = NULL;
37 int w, h;
38 OMX_COLOR_FORMATTYPE pixFormat;
39 CodingMode codingMode = mCodingMode;
40 const char *valstr = NULL;
41 int varint = 0;
42 OMX_TI_STEREOFRAMELAYOUTTYPE capFrmLayout;
43 bool inCaptureState = false;
44
45 LOG_FUNCTION_NAME;
46
47 OMXCameraPortParameters *cap;
48 cap = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
49
50 capFrmLayout = cap->mFrameLayoutType;
51 setParamS3D(mCameraAdapterParameters.mImagePortIndex,
52 params.get(TICameraParameters::KEY_S3D_CAP_FRAME_LAYOUT));
53 if (capFrmLayout != cap->mFrameLayoutType) {
54 mPendingCaptureSettings |= SetFormat;
55 }
56
57 params.getPictureSize(&w, &h);
58
59 if ( ( w != ( int ) cap->mWidth ) ||
60 ( h != ( int ) cap->mHeight ) )
61 {
62 mPendingCaptureSettings |= SetFormat;
63 }
64
65 cap->mWidth = w;
66 cap->mHeight = h;
67 //TODO: Support more pixelformats
68 //cap->mStride = 2;
69
70 CAMHAL_LOGVB("Image: cap.mWidth = %d", (int)cap->mWidth);
71 CAMHAL_LOGVB("Image: cap.mHeight = %d", (int)cap->mHeight);
72
73 if ((valstr = params.getPictureFormat()) != NULL) {
74 if (strcmp(valstr, android::CameraParameters::PIXEL_FORMAT_YUV422I) == 0) {
75 CAMHAL_LOGDA("CbYCrY format selected");
76 pixFormat = OMX_COLOR_FormatCbYCrY;
77 mPictureFormatFromClient = android::CameraParameters::PIXEL_FORMAT_YUV422I;
78 } else if(strcmp(valstr, android::CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) {
79 CAMHAL_LOGDA("YUV420SP format selected");
80 pixFormat = OMX_COLOR_FormatYUV420SemiPlanar;
81 mPictureFormatFromClient = android::CameraParameters::PIXEL_FORMAT_YUV420SP;
82 } else if(strcmp(valstr, android::CameraParameters::PIXEL_FORMAT_RGB565) == 0) {
83 CAMHAL_LOGDA("RGB565 format selected");
84 pixFormat = OMX_COLOR_Format16bitRGB565;
85 mPictureFormatFromClient = android::CameraParameters::PIXEL_FORMAT_RGB565;
86 } else if (strcmp(valstr, android::CameraParameters::PIXEL_FORMAT_JPEG) == 0) {
87 CAMHAL_LOGDA("JPEG format selected");
88 pixFormat = OMX_COLOR_FormatUnused;
89 codingMode = CodingJPEG;
90 mPictureFormatFromClient = android::CameraParameters::PIXEL_FORMAT_JPEG;
91 } else if (strcmp(valstr, TICameraParameters::PIXEL_FORMAT_JPS) == 0) {
92 CAMHAL_LOGDA("JPS format selected");
93 pixFormat = OMX_COLOR_FormatUnused;
94 codingMode = CodingJPS;
95 mPictureFormatFromClient = TICameraParameters::PIXEL_FORMAT_JPS;
96 } else if (strcmp(valstr, TICameraParameters::PIXEL_FORMAT_MPO) == 0) {
97 CAMHAL_LOGDA("MPO format selected");
98 pixFormat = OMX_COLOR_FormatUnused;
99 codingMode = CodingMPO;
100 mPictureFormatFromClient = TICameraParameters::PIXEL_FORMAT_MPO;
101 } else if (strcmp(valstr, android::CameraParameters::PIXEL_FORMAT_BAYER_RGGB) == 0) {
102 CAMHAL_LOGDA("RAW Picture format selected");
103 pixFormat = OMX_COLOR_FormatRawBayer10bit;
104 mPictureFormatFromClient = android::CameraParameters::PIXEL_FORMAT_BAYER_RGGB;
105 } else {
106 CAMHAL_LOGEA("Invalid format, JPEG format selected as default");
107 pixFormat = OMX_COLOR_FormatUnused;
108 codingMode = CodingJPEG;
109 mPictureFormatFromClient = NULL;
110 }
111 } else {
112 CAMHAL_LOGEA("Picture format is NULL, defaulting to JPEG");
113 pixFormat = OMX_COLOR_FormatUnused;
114 codingMode = CodingJPEG;
115 mPictureFormatFromClient = NULL;
116 }
117
118 #ifdef CAMERAHAL_USE_RAW_IMAGE_SAVING
119 mRawCapture = false;
120 mYuvCapture = false;
121
122 valstr = params.get(TICameraParameters::KEY_CAP_MODE);
123 if ( (!valstr || strcmp(valstr, TICameraParameters::HIGH_QUALITY_MODE) == 0) &&
124 access(kRawImagesOutputDirPath, F_OK) != -1 ) {
125 mRawCapture = true;
126 }
127
128 if (mRawCapture && (access(kYuvImagesOutputDirPath, F_OK) != -1)) {
129 pixFormat = OMX_COLOR_FormatCbYCrY;
130 mYuvCapture = true;
131 }
132 #endif
133 // JPEG capture is not supported in video mode by OMX Camera
134 // Set capture format to yuv422i...jpeg encode will
135 // be done on A9
136 valstr = params.get(TICameraParameters::KEY_CAP_MODE);
137 if ( (valstr && ( strcmp(valstr, (const char *) TICameraParameters::VIDEO_MODE) == 0 ||
138 strcmp(valstr, (const char *) TICameraParameters::VIDEO_MODE_HQ) == 0 ) ) &&
139 (pixFormat == OMX_COLOR_FormatUnused) ) {
140 CAMHAL_LOGDA("Capturing in video mode...selecting yuv422i");
141 pixFormat = OMX_COLOR_FormatCbYCrY;
142 }
143
144 if (pixFormat != cap->mColorFormat || codingMode != mCodingMode) {
145 mPendingCaptureSettings |= SetFormat;
146 cap->mColorFormat = pixFormat;
147 mCodingMode = codingMode;
148 }
149
150 #ifdef OMAP_ENHANCEMENT
151 str = params.get(TICameraParameters::KEY_TEMP_BRACKETING);
152 if ( ( str != NULL ) &&
153 ( strcmp(str, android::CameraParameters::TRUE) == 0 ) ) {
154
155 if ( !mBracketingSet ) {
156 mPendingCaptureSettings |= SetBurstExpBracket;
157 }
158
159 mBracketingSet = true;
160 } else {
161
162 if ( mBracketingSet ) {
163 mPendingCaptureSettings |= SetBurstExpBracket;
164 }
165
166 mBracketingSet = false;
167 }
168
169 if ( (str = params.get(TICameraParameters::KEY_EXP_BRACKETING_RANGE)) != NULL ) {
170 parseExpRange(str, mExposureBracketingValues, NULL,
171 mExposureGainBracketingModes,
172 EXP_BRACKET_RANGE, mExposureBracketingValidEntries);
173 if (mCapMode == OMXCameraAdapter::CP_CAM) {
174 mExposureBracketMode = OMX_BracketVectorShot;
175 } else {
176 mExposureBracketMode = OMX_BracketExposureRelativeInEV;
177 }
178 mPendingCaptureSettings |= SetBurstExpBracket;
179 } else if ( (str = params.get(TICameraParameters::KEY_EXP_GAIN_BRACKETING_RANGE)) != NULL) {
180 parseExpRange(str, mExposureBracketingValues, mExposureGainBracketingValues,
181 mExposureGainBracketingModes,
182 EXP_BRACKET_RANGE, mExposureBracketingValidEntries);
183 if (mCapMode == OMXCameraAdapter::CP_CAM) {
184 mExposureBracketMode = OMX_BracketVectorShot;
185 } else {
186 mExposureBracketMode = OMX_BracketExposureGainAbsolute;
187 }
188 mPendingCaptureSettings |= SetBurstExpBracket;
189 } else {
190 // always set queued shot config in CPCAM mode
191 if (mCapMode == OMXCameraAdapter::CP_CAM) {
192 mExposureBracketMode = OMX_BracketVectorShot;
193 mPendingCaptureSettings |= SetBurstExpBracket;
194 }
195 // if bracketing was previously set...we set again before capturing to clear
196 if (mExposureBracketingValidEntries) {
197 mPendingCaptureSettings |= SetBurstExpBracket;
198 mExposureBracketingValidEntries = 0;
199 }
200 }
201
202 str = params.get(TICameraParameters::KEY_ZOOM_BRACKETING_RANGE);
203 if ( NULL != str ) {
204 parseExpRange(str, mZoomBracketingValues, NULL, NULL,
205 ZOOM_BRACKET_RANGE, mZoomBracketingValidEntries);
206 mCurrentZoomBracketing = 0;
207 mZoomBracketingEnabled = true;
208 } else {
209 if (mZoomBracketingValidEntries) {
210 mZoomBracketingValidEntries = 0;
211 }
212 mZoomBracketingEnabled = false;
213 }
214 #endif
215
216 // Flush config queue
217 // If TRUE: Flush queue and abort processing before enqueing
218 valstr = params.get(TICameraParameters::KEY_FLUSH_SHOT_CONFIG_QUEUE);
219 if ( NULL != valstr ) {
220 if ( 0 == strcmp(valstr, android::CameraParameters::TRUE) ) {
221 mFlushShotConfigQueue = true;
222 } else if ( 0 == strcmp(valstr, android::CameraParameters::FALSE) ) {
223 mFlushShotConfigQueue = false;
224 } else {
225 CAMHAL_LOGE("Missing flush shot config parameter. Will use current (%s)",
226 mFlushShotConfigQueue ? "true" : "false");
227 }
228 }
229
230 if ( params.getInt(android::CameraParameters::KEY_ROTATION) != -1 )
231 {
232 if (params.getInt(android::CameraParameters::KEY_ROTATION) != (int) mPictureRotation) {
233 mPendingCaptureSettings |= SetRotation;
234 }
235 mPictureRotation = params.getInt(android::CameraParameters::KEY_ROTATION);
236 }
237 else
238 {
239 if (mPictureRotation) mPendingCaptureSettings |= SetRotation;
240 mPictureRotation = 0;
241 }
242
243 CAMHAL_LOGVB("Picture Rotation set %d", mPictureRotation);
244
245 #ifdef OMAP_ENHANCEMENT
246 // Read Sensor Orientation and set it based on perating mode
247 varint = params.getInt(TICameraParameters::KEY_SENSOR_ORIENTATION);
248 if ( varint != -1 )
249 {
250 mSensorOrientation = varint;
251 if (mSensorOrientation == 270 ||mSensorOrientation==90)
252 {
253 CAMHAL_LOGEA(" Orientation is 270/90. So setting counter rotation to Ducati");
254 mSensorOrientation +=180;
255 mSensorOrientation%=360;
256 }
257 }
258 else
259 {
260 mSensorOrientation = 0;
261 }
262
263 CAMHAL_LOGVB("Sensor Orientation set : %d", mSensorOrientation);
264 #endif
265
266 #ifdef OMAP_ENHANCEMENT_BURST_CAPTURE
267 varint = params.getInt(TICameraParameters::KEY_BURST);
268 if ( varint >= 1 )
269 {
270 if (varint != (int) mBurstFrames) {
271 mPendingCaptureSettings |= SetBurstExpBracket;
272 }
273 mBurstFrames = varint;
274 }
275 else
276 {
277 if (mBurstFrames != 1) mPendingCaptureSettings |= SetBurstExpBracket;
278 mBurstFrames = 1;
279 }
280
281 CAMHAL_LOGVB("Burst Frames set %d", mBurstFrames);
282 #endif
283
284 varint = params.getInt(android::CameraParameters::KEY_JPEG_QUALITY);
285 if ( varint >= MIN_JPEG_QUALITY && varint <= MAX_JPEG_QUALITY ) {
286 if (varint != mPictureQuality) {
287 mPendingCaptureSettings |= SetQuality;
288 mPictureQuality = varint;
289 }
290 } else {
291 if (mPictureQuality != MAX_JPEG_QUALITY) {
292 mPendingCaptureSettings |= SetQuality;
293 mPictureQuality = MAX_JPEG_QUALITY;
294 }
295 }
296
297 CAMHAL_LOGVB("Picture Quality set %d", mPictureQuality);
298
299 varint = params.getInt(android::CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
300 if ( varint >= 0 ) {
301 if (varint != mThumbWidth) {
302 mPendingCaptureSettings |= SetThumb;
303 mThumbWidth = varint;
304 }
305 } else {
306 if (mThumbWidth != DEFAULT_THUMB_WIDTH) {
307 mPendingCaptureSettings |= SetThumb;
308 mThumbWidth = DEFAULT_THUMB_WIDTH;
309 }
310 }
311
312 CAMHAL_LOGVB("Picture Thumb width set %d", mThumbWidth);
313
314 varint = params.getInt(android::CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
315 if ( varint >= 0 ) {
316 if (varint != mThumbHeight) {
317 mPendingCaptureSettings |= SetThumb;
318 mThumbHeight = varint;
319 }
320 } else {
321 if (mThumbHeight != DEFAULT_THUMB_HEIGHT) {
322 mPendingCaptureSettings |= SetThumb;
323 mThumbHeight = DEFAULT_THUMB_HEIGHT;
324 }
325 }
326
327 CAMHAL_LOGVB("Picture Thumb height set %d", mThumbHeight);
328
329 varint = params.getInt(android::CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
330 if ( varint >= MIN_JPEG_QUALITY && varint <= MAX_JPEG_QUALITY ) {
331 if (varint != mThumbQuality) {
332 mPendingCaptureSettings |= SetThumb;
333 mThumbQuality = varint;
334 }
335 } else {
336 if (mThumbQuality != MAX_JPEG_QUALITY) {
337 mPendingCaptureSettings |= SetThumb;
338 mThumbQuality = MAX_JPEG_QUALITY;
339 }
340 }
341
342 CAMHAL_LOGDB("Thumbnail Quality set %d", mThumbQuality);
343
344 if (mFirstTimeInit) {
345 mPendingCaptureSettings = ECapturesettingsAll;
346 }
347
348 cap = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoPortIndex];
349 cap->mWidth = params.getInt(TICameraParameters::RAW_WIDTH);
350 cap->mHeight = params.getInt(TICameraParameters::RAW_HEIGHT);
351
352 LOG_FUNCTION_NAME_EXIT;
353
354 return ret;
355 }
356
getPictureBufferSize(CameraFrame & frame,size_t bufferCount)357 status_t OMXCameraAdapter::getPictureBufferSize(CameraFrame &frame, size_t bufferCount)
358 {
359 status_t ret = NO_ERROR;
360 OMXCameraPortParameters *imgCaptureData = NULL;
361 OMX_ERRORTYPE eError = OMX_ErrorNone;
362
363 LOG_FUNCTION_NAME;
364
365 if ( NO_ERROR == ret )
366 {
367 imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
368
369
370 // If any settings have changed that need to be set with SetParam,
371 // we will need to disable the port to set them
372 if ((mPendingCaptureSettings & ECaptureParamSettings)) {
373 disableImagePort();
374 if ( NULL != mReleaseImageBuffersCallback ) {
375 mReleaseImageBuffersCallback(mReleaseData);
376 }
377 }
378
379 if (mPendingCaptureSettings & SetFormat) {
380 ret = setFormat(OMX_CAMERA_PORT_IMAGE_OUT_IMAGE, *imgCaptureData);
381 }
382
383 if ( ret == NO_ERROR )
384 {
385 frame.mLength = imgCaptureData->mBufSize;
386 frame.mWidth = imgCaptureData->mWidth;
387 frame.mHeight = imgCaptureData->mHeight;
388 frame.mAlignment = imgCaptureData->mStride;
389 CAMHAL_LOGDB("getPictureBufferSize: width:%u height:%u alignment:%u length:%u",
390 frame.mWidth, frame.mHeight, frame.mAlignment, frame.mLength);
391 }
392 else
393 {
394 CAMHAL_LOGEB("setFormat() failed 0x%x", ret);
395 }
396 }
397
398 LOG_FUNCTION_NAME_EXIT;
399
400 return ret;
401 }
402
getBracketingValueMode(const char * a,const char * b) const403 int OMXCameraAdapter::getBracketingValueMode(const char *a, const char *b) const
404 {
405 BracketingValueMode bvm = BracketingValueAbsolute;
406
407 if ( (NULL != b) &&
408 (NULL != a) &&
409 (a < b) &&
410 ( (NULL != memchr(a, '+', b - a)) ||
411 (NULL != memchr(a, '-', b - a)) ) ) {
412 bvm = BracketingValueRelative;
413 }
414 return bvm;
415 }
416
parseExpRange(const char * rangeStr,int * expRange,int * gainRange,int * expGainModes,size_t count,size_t & validEntries)417 status_t OMXCameraAdapter::parseExpRange(const char *rangeStr,
418 int *expRange,
419 int *gainRange,
420 int *expGainModes,
421 size_t count,
422 size_t &validEntries)
423 {
424 status_t ret = NO_ERROR;
425 char *end = NULL;
426 const char *startPtr = NULL;
427 size_t i = 0;
428
429 LOG_FUNCTION_NAME;
430
431 if ( NULL == rangeStr ){
432 return -EINVAL;
433 }
434
435 if ( NULL == expRange ){
436 return -EINVAL;
437 }
438
439 if ( NO_ERROR == ret ) {
440 startPtr = rangeStr;
441 do {
442 // Relative Exposure example: "-30,-10, 0, 10, 30"
443 // Absolute Gain ex. (exposure,gain) pairs: "(100,300),(200,300),(400,300),(800,300),(1600,300)"
444 // Relative Gain ex. (exposure,gain) pairs: "(-30,+0),(-10, +0),(+0,+0),(+10,+0),(+30,+0)"
445 // Forced relative Exposure example: "-30F,-10F, 0F, 10F, 30F"
446 // Forced absolute Gain ex. (exposure,gain) pairs: "(100,300)F,(200,300)F,(400,300)F,(800,300)F,(1600,300)F"
447 // Forced relative Gain ex. (exposure,gain) pairs: "(-30,+0)F,(-10, +0)F,(+0,+0)F,(+10,+0)F,(+30,+0)F"
448
449 // skip '(' and ','
450 while ((*startPtr == '(') || (*startPtr == ',')) startPtr++;
451
452 expRange[i] = (int)strtol(startPtr, &end, 10);
453
454 if (expGainModes) {
455 // if gainRange is given rangeStr should be (exposure, gain) pair
456 if (gainRange) {
457 int bvm_exp = getBracketingValueMode(startPtr, end);
458 startPtr = end + 1; // for the ','
459 gainRange[i] = (int)strtol(startPtr, &end, 10);
460
461 if (BracketingValueAbsolute == bvm_exp) {
462 expGainModes[i] = getBracketingValueMode(startPtr, end);
463 } else {
464 expGainModes[i] = bvm_exp;
465 }
466 } else {
467 expGainModes[i] = BracketingValueCompensation;
468 }
469 }
470 startPtr = end;
471
472 // skip ')'
473 while (*startPtr == ')') startPtr++;
474
475 // Check for "forced" key
476 if (expGainModes) {
477 while ((*startPtr == 'F') || (*startPtr == 'f')) {
478 if ( BracketingValueAbsolute == expGainModes[i] ) {
479 expGainModes[i] = BracketingValueAbsoluteForced;
480 } else if ( BracketingValueRelative == expGainModes[i] ) {
481 expGainModes[i] = BracketingValueRelativeForced;
482 } else if ( BracketingValueCompensation == expGainModes[i] ) {
483 expGainModes[i] = BracketingValueCompensationForced;
484 } else {
485 CAMHAL_LOGE("Unexpected old mode 0x%x", expGainModes[i]);
486 }
487 startPtr++;
488 }
489 }
490
491 i++;
492
493 } while ((startPtr[0] != '\0') && (i < count));
494 validEntries = i;
495 }
496
497 LOG_FUNCTION_NAME_EXIT;
498
499 return ret;
500 }
501
doExposureBracketing(int * evValues,int * evValues2,int * evModes2,size_t evCount,size_t frameCount,bool flush,OMX_BRACKETMODETYPE bracketMode)502 status_t OMXCameraAdapter::doExposureBracketing(int *evValues,
503 int *evValues2,
504 int *evModes2,
505 size_t evCount,
506 size_t frameCount,
507 bool flush,
508 OMX_BRACKETMODETYPE bracketMode)
509 {
510 status_t ret = NO_ERROR;
511
512 LOG_FUNCTION_NAME;
513
514 if ( OMX_StateInvalid == mComponentState ) {
515 CAMHAL_LOGEA("OMX component is in invalid state");
516 ret = -EINVAL;
517 }
518
519 if ( NULL == evValues ) {
520 CAMHAL_LOGEA("Exposure compensation values pointer is invalid");
521 ret = -EINVAL;
522 }
523
524 if ( NO_ERROR == ret ) {
525 if (bracketMode == OMX_BracketVectorShot) {
526 ret = setVectorShot(evValues, evValues2, evModes2, evCount, frameCount, flush, bracketMode);
527 } else {
528 ret = setExposureBracketing(evValues, evValues2, evCount, frameCount, bracketMode);
529 }
530 }
531
532 LOG_FUNCTION_NAME_EXIT;
533
534 return ret;
535 }
536
setVectorStop(bool toPreview)537 status_t OMXCameraAdapter::setVectorStop(bool toPreview)
538 {
539 status_t ret = NO_ERROR;
540 OMX_ERRORTYPE eError = OMX_ErrorNone;
541 OMX_TI_CONFIG_VECTSHOTSTOPMETHODTYPE vecShotStop;
542
543
544 LOG_FUNCTION_NAME;
545
546 OMX_INIT_STRUCT_PTR(&vecShotStop, OMX_TI_CONFIG_VECTSHOTSTOPMETHODTYPE);
547
548 vecShotStop.nPortIndex = mCameraAdapterParameters.mImagePortIndex;
549 if (toPreview) {
550 vecShotStop.eStopMethod = OMX_TI_VECTSHOTSTOPMETHOD_GOTO_PREVIEW;
551 } else {
552 vecShotStop.eStopMethod = OMX_TI_VECTSHOTSTOPMETHOD_WAIT_IN_CAPTURE;
553 }
554
555 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
556 (OMX_INDEXTYPE) OMX_TI_IndexConfigVectShotStopMethod,
557 &vecShotStop);
558 if (OMX_ErrorNone != eError) {
559 CAMHAL_LOGEB("Error while configuring bracket shot 0x%x", eError);
560 } else {
561 CAMHAL_LOGDA("Bracket shot configured successfully");
562 }
563
564 LOG_FUNCTION_NAME_EXIT;
565
566 return (ret | Utils::ErrorUtils::omxToAndroidError(eError));
567 }
568
initVectorShot()569 status_t OMXCameraAdapter::initVectorShot()
570 {
571 status_t ret = NO_ERROR;
572 OMX_ERRORTYPE eError = OMX_ErrorNone;
573 OMX_CONFIG_CAPTUREMODETYPE expCapMode;
574 OMX_CONFIG_EXTCAPTUREMODETYPE extExpCapMode;
575
576 LOG_FUNCTION_NAME;
577
578 if (NO_ERROR == ret) {
579 OMX_INIT_STRUCT_PTR (&expCapMode, OMX_CONFIG_CAPTUREMODETYPE);
580 expCapMode.nPortIndex = mCameraAdapterParameters.mImagePortIndex;
581
582 expCapMode.bFrameLimited = OMX_FALSE;
583
584 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
585 OMX_IndexConfigCaptureMode,
586 &expCapMode);
587 if (OMX_ErrorNone != eError) {
588 CAMHAL_LOGEB("Error while configuring capture mode 0x%x", eError);
589 goto exit;
590 } else {
591 CAMHAL_LOGDA("Camera capture mode configured successfully");
592 }
593 }
594
595 if (NO_ERROR == ret) {
596 OMX_INIT_STRUCT_PTR (&extExpCapMode, OMX_CONFIG_EXTCAPTUREMODETYPE);
597 extExpCapMode.nPortIndex = mCameraAdapterParameters.mImagePortIndex;
598
599 extExpCapMode.bEnableBracketing = OMX_TRUE;
600 extExpCapMode.tBracketConfigType.eBracketMode = OMX_BracketVectorShot;
601
602 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
603 ( OMX_INDEXTYPE ) OMX_IndexConfigExtCaptureMode,
604 &extExpCapMode);
605 if ( OMX_ErrorNone != eError ) {
606 CAMHAL_LOGEB("Error while configuring extended capture mode 0x%x", eError);
607 goto exit;
608 } else {
609 CAMHAL_LOGDA("Extended camera capture mode configured successfully");
610 }
611 }
612
613
614 if (NO_ERROR == ret) {
615 // set vector stop method to stop in capture
616 ret = setVectorStop(false);
617 }
618
619 exit:
620 LOG_FUNCTION_NAME_EXIT;
621
622 return (ret | Utils::ErrorUtils::omxToAndroidError(eError));
623 }
624
setVectorShot(int * evValues,int * evValues2,int * evModes2,size_t evCount,size_t frameCount,bool flush,OMX_BRACKETMODETYPE bracketMode)625 status_t OMXCameraAdapter::setVectorShot(int *evValues,
626 int *evValues2,
627 int *evModes2,
628 size_t evCount,
629 size_t frameCount,
630 bool flush,
631 OMX_BRACKETMODETYPE bracketMode)
632 {
633 status_t ret = NO_ERROR;
634 OMX_ERRORTYPE eError = OMX_ErrorNone;
635 OMX_TI_CONFIG_ENQUEUESHOTCONFIGS enqueueShotConfigs;
636 OMX_TI_CONFIG_QUERYAVAILABLESHOTS queryAvailableShots;
637 bool doFlush = flush;
638
639 LOG_FUNCTION_NAME;
640
641 OMX_INIT_STRUCT_PTR(&enqueueShotConfigs, OMX_TI_CONFIG_ENQUEUESHOTCONFIGS);
642 OMX_INIT_STRUCT_PTR(&queryAvailableShots, OMX_TI_CONFIG_QUERYAVAILABLESHOTS);
643
644 queryAvailableShots.nPortIndex = mCameraAdapterParameters.mImagePortIndex;
645 eError = OMX_GetConfig(mCameraAdapterParameters.mHandleComp,
646 (OMX_INDEXTYPE) OMX_TI_IndexConfigQueryAvailableShots,
647 &queryAvailableShots);
648 if (OMX_ErrorNone != eError) {
649 CAMHAL_LOGE("Error getting available shots 0x%x", eError);
650 goto exit;
651 } else {
652 CAMHAL_LOGD("AVAILABLE SHOTS: %d", queryAvailableShots.nAvailableShots);
653 if (queryAvailableShots.nAvailableShots < evCount) {
654 // TODO(XXX): Need to implement some logic to handle this error
655 CAMHAL_LOGE("Not enough available shots to fulfill this queue request");
656 ret = -ENOSPC;
657 goto exit;
658 }
659 }
660
661 for ( unsigned int confID = 0; confID < evCount; ) {
662 unsigned int i;
663 for ( i = 0 ; (i < ARRAY_SIZE(enqueueShotConfigs.nShotConfig)) && (confID < evCount); i++, confID++ ) {
664 CAMHAL_LOGD("%2u: (%7d,%4d) mode: %d", confID, evValues[confID], evValues2[confID], evModes2[confID]);
665 enqueueShotConfigs.nShotConfig[i].nConfigId = confID;
666 enqueueShotConfigs.nShotConfig[i].nFrames = 1;
667 if ( (BracketingValueCompensation == evModes2[confID]) ||
668 (BracketingValueCompensationForced == evModes2[confID]) ) {
669 // EV compensation
670 enqueueShotConfigs.nShotConfig[i].nEC = evValues[confID];
671 enqueueShotConfigs.nShotConfig[i].nExp = 0;
672 enqueueShotConfigs.nShotConfig[i].nGain = 0;
673 } else {
674 // exposure,gain pair
675 enqueueShotConfigs.nShotConfig[i].nEC = 0;
676 enqueueShotConfigs.nShotConfig[i].nExp = evValues[confID];
677 enqueueShotConfigs.nShotConfig[i].nGain = evValues2[confID];
678 }
679 enqueueShotConfigs.nShotConfig[i].eExpGainApplyMethod = OMX_TI_EXPGAINAPPLYMETHOD_ABSOLUTE;
680 switch (evModes2[confID]) {
681 case BracketingValueAbsolute: // (exp,gain) pairs directly program sensor values
682 default :
683 enqueueShotConfigs.nShotConfig[i].eExpGainApplyMethod = OMX_TI_EXPGAINAPPLYMETHOD_ABSOLUTE;
684 break;
685 case BracketingValueRelative: // (exp,gain) pairs relative to AE settings and constraints
686 case BracketingValueCompensation: // EV compensation relative to AE settings and constraints
687 enqueueShotConfigs.nShotConfig[i].eExpGainApplyMethod = OMX_TI_EXPGAINAPPLYMETHOD_RELATIVE;
688 break;
689 case BracketingValueAbsoluteForced: // (exp,gain) pairs directly program sensor values
690 // are forced over constraints due to flicker, etc.
691 enqueueShotConfigs.nShotConfig[i].eExpGainApplyMethod = OMX_TI_EXPGAINAPPLYMETHOD_FORCE_ABSOLUTE;
692 break;
693 case BracketingValueRelativeForced: // (exp, gain) pairs relative to AE settings AND settings
694 case BracketingValueCompensationForced: // EV compensation relative to AE settings and constraints
695 // are forced over constraints due to flicker, etc.
696 enqueueShotConfigs.nShotConfig[i].eExpGainApplyMethod = OMX_TI_EXPGAINAPPLYMETHOD_FORCE_RELATIVE;
697 break;
698 }
699 enqueueShotConfigs.nShotConfig[i].bNoSnapshot = OMX_FALSE; // TODO: Make this configurable
700 }
701
702 // Repeat last exposure and again
703 if ((confID == evCount) && (evCount > 0) && (frameCount > evCount) && (0 != i)) {
704 enqueueShotConfigs.nShotConfig[i-1].nFrames = frameCount - evCount;
705 }
706
707 enqueueShotConfigs.nPortIndex = mCameraAdapterParameters.mImagePortIndex;
708 enqueueShotConfigs.bFlushQueue = doFlush ? OMX_TRUE : OMX_FALSE;
709 enqueueShotConfigs.nNumConfigs = i;
710 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
711 ( OMX_INDEXTYPE ) OMX_TI_IndexConfigEnqueueShotConfigs,
712 &enqueueShotConfigs);
713 if ( OMX_ErrorNone != eError ) {
714 CAMHAL_LOGEB("Error while configuring enqueue shot 0x%x", eError);
715 goto exit;
716 } else {
717 CAMHAL_LOGDA("Enqueue shot configured successfully");
718 }
719 // Flush only first time
720 doFlush = false;
721 }
722
723 // Handle burst capture (no any bracketing) case
724 if (0 == evCount) {
725 CAMHAL_LOGE("Handle burst capture (no any bracketing) case");
726 enqueueShotConfigs.nShotConfig[0].nConfigId = 0;
727 enqueueShotConfigs.nShotConfig[0].nFrames = frameCount;
728 enqueueShotConfigs.nShotConfig[0].nEC = 0;
729 enqueueShotConfigs.nShotConfig[0].nExp = 0;
730 enqueueShotConfigs.nShotConfig[0].nGain = 0;
731 enqueueShotConfigs.nShotConfig[0].eExpGainApplyMethod = OMX_TI_EXPGAINAPPLYMETHOD_RELATIVE;
732 enqueueShotConfigs.nShotConfig[0].bNoSnapshot = OMX_FALSE; // TODO: Make this configurable
733 enqueueShotConfigs.nNumConfigs = 1;
734 enqueueShotConfigs.nPortIndex = mCameraAdapterParameters.mImagePortIndex;
735 enqueueShotConfigs.bFlushQueue = doFlush ? OMX_TRUE : OMX_FALSE;
736 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
737 ( OMX_INDEXTYPE ) OMX_TI_IndexConfigEnqueueShotConfigs,
738 &enqueueShotConfigs);
739 if ( OMX_ErrorNone != eError ) {
740 CAMHAL_LOGEB("Error while configuring enqueue shot 0x%x", eError);
741 goto exit;
742 } else {
743 CAMHAL_LOGDA("Enqueue shot configured successfully");
744 }
745 }
746
747 exit:
748 LOG_FUNCTION_NAME_EXIT;
749
750 return (ret | Utils::ErrorUtils::omxToAndroidError(eError));
751 }
752
setExposureBracketing(int * evValues,int * evValues2,size_t evCount,size_t frameCount,OMX_BRACKETMODETYPE bracketMode)753 status_t OMXCameraAdapter::setExposureBracketing(int *evValues,
754 int *evValues2,
755 size_t evCount,
756 size_t frameCount,
757 OMX_BRACKETMODETYPE bracketMode)
758 {
759 status_t ret = NO_ERROR;
760 OMX_ERRORTYPE eError = OMX_ErrorNone;
761 OMX_CONFIG_CAPTUREMODETYPE expCapMode;
762 OMX_CONFIG_EXTCAPTUREMODETYPE extExpCapMode;
763
764 LOG_FUNCTION_NAME;
765
766 if ( NO_ERROR == ret )
767 {
768 OMX_INIT_STRUCT_PTR (&expCapMode, OMX_CONFIG_CAPTUREMODETYPE);
769 expCapMode.nPortIndex = mCameraAdapterParameters.mImagePortIndex;
770
771 /// If frameCount>0 but evCount<=0, then this is the case of HQ burst.
772 //Otherwise, it is normal HQ capture
773 ///If frameCount>0 and evCount>0 then this is the cause of HQ Exposure bracketing.
774 if ( 0 == evCount && 0 == frameCount )
775 {
776 expCapMode.bFrameLimited = OMX_FALSE;
777 }
778 else
779 {
780 expCapMode.bFrameLimited = OMX_TRUE;
781 expCapMode.nFrameLimit = frameCount;
782 }
783
784 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
785 OMX_IndexConfigCaptureMode,
786 &expCapMode);
787 if ( OMX_ErrorNone != eError )
788 {
789 CAMHAL_LOGEB("Error while configuring capture mode 0x%x", eError);
790 }
791 else
792 {
793 CAMHAL_LOGDA("Camera capture mode configured successfully");
794 }
795 }
796
797 if ( NO_ERROR == ret )
798 {
799 OMX_INIT_STRUCT_PTR (&extExpCapMode, OMX_CONFIG_EXTCAPTUREMODETYPE);
800 extExpCapMode.nPortIndex = mCameraAdapterParameters.mImagePortIndex;
801
802 if ( 0 == evCount )
803 {
804 extExpCapMode.bEnableBracketing = OMX_FALSE;
805 }
806 else
807 {
808 extExpCapMode.bEnableBracketing = OMX_TRUE;
809 extExpCapMode.tBracketConfigType.eBracketMode = bracketMode;
810 extExpCapMode.tBracketConfigType.nNbrBracketingValues = evCount - 1;
811 }
812
813 for ( unsigned int i = 0 ; i < evCount ; i++ )
814 {
815 if (bracketMode == OMX_BracketExposureGainAbsolute) {
816 extExpCapMode.tBracketConfigType.nBracketValues[i] = evValues[i];
817 extExpCapMode.tBracketConfigType.nBracketValues2[i] = evValues2[i];
818 } else {
819 // assuming OMX_BracketExposureRelativeInEV
820 extExpCapMode.tBracketConfigType.nBracketValues[i] = ( evValues[i] * ( 1 << Q16_OFFSET ) ) / 10;
821 }
822 }
823
824 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
825 ( OMX_INDEXTYPE ) OMX_IndexConfigExtCaptureMode,
826 &extExpCapMode);
827 if ( OMX_ErrorNone != eError )
828 {
829 CAMHAL_LOGEB("Error while configuring extended capture mode 0x%x", eError);
830 }
831 else
832 {
833 CAMHAL_LOGDA("Extended camera capture mode configured successfully");
834 }
835 }
836
837 LOG_FUNCTION_NAME_EXIT;
838
839 return ret;
840 }
841
setShutterCallback(bool enabled)842 status_t OMXCameraAdapter::setShutterCallback(bool enabled)
843 {
844 status_t ret = NO_ERROR;
845 OMX_ERRORTYPE eError = OMX_ErrorNone;
846 OMX_CONFIG_CALLBACKREQUESTTYPE shutterRequstCallback;
847
848 LOG_FUNCTION_NAME;
849
850 if ( OMX_StateExecuting != mComponentState )
851 {
852 CAMHAL_LOGEA("OMX component not in executing state");
853 ret = -1;
854 }
855
856 if ( NO_ERROR == ret )
857 {
858
859 OMX_INIT_STRUCT_PTR (&shutterRequstCallback, OMX_CONFIG_CALLBACKREQUESTTYPE);
860 shutterRequstCallback.nPortIndex = OMX_ALL;
861
862 if ( enabled )
863 {
864 shutterRequstCallback.bEnable = OMX_TRUE;
865 shutterRequstCallback.nIndex = ( OMX_INDEXTYPE ) OMX_TI_IndexConfigShutterCallback;
866 CAMHAL_LOGDA("Enabling shutter callback");
867 }
868 else
869 {
870 shutterRequstCallback.bEnable = OMX_FALSE;
871 shutterRequstCallback.nIndex = ( OMX_INDEXTYPE ) OMX_TI_IndexConfigShutterCallback;
872 CAMHAL_LOGDA("Disabling shutter callback");
873 }
874
875 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
876 ( OMX_INDEXTYPE ) OMX_IndexConfigCallbackRequest,
877 &shutterRequstCallback);
878 if ( OMX_ErrorNone != eError )
879 {
880 CAMHAL_LOGEB("Error registering shutter callback 0x%x", eError);
881 ret = -1;
882 }
883 else
884 {
885 CAMHAL_LOGDB("Shutter callback for index 0x%x registered successfully",
886 OMX_TI_IndexConfigShutterCallback);
887 }
888 }
889
890 LOG_FUNCTION_NAME_EXIT;
891
892 return ret;
893 }
894
doBracketing(OMX_BUFFERHEADERTYPE * pBuffHeader,CameraFrame::FrameType typeOfFrame)895 status_t OMXCameraAdapter::doBracketing(OMX_BUFFERHEADERTYPE *pBuffHeader,
896 CameraFrame::FrameType typeOfFrame)
897 {
898 status_t ret = NO_ERROR;
899 int currentBufferIdx, nextBufferIdx;
900 OMXCameraPortParameters * imgCaptureData = NULL;
901
902 LOG_FUNCTION_NAME;
903
904 imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
905
906 if ( OMX_StateExecuting != mComponentState )
907 {
908 CAMHAL_LOGEA("OMX component is not in executing state");
909 ret = -EINVAL;
910 }
911
912 if ( NO_ERROR == ret )
913 {
914 CameraBuffer *buffer = (CameraBuffer *)pBuffHeader->pAppPrivate;
915 currentBufferIdx = buffer->index;
916
917 if ( currentBufferIdx >= imgCaptureData->mNumBufs)
918 {
919 CAMHAL_LOGEB("Invalid bracketing buffer index 0x%x", currentBufferIdx);
920 ret = -EINVAL;
921 }
922 }
923
924 if ( NO_ERROR == ret )
925 {
926 mBracketingBuffersQueued[currentBufferIdx] = false;
927 mBracketingBuffersQueuedCount--;
928
929 if ( 0 >= mBracketingBuffersQueuedCount )
930 {
931 nextBufferIdx = ( currentBufferIdx + 1 ) % imgCaptureData->mNumBufs;
932 mBracketingBuffersQueued[nextBufferIdx] = true;
933 mBracketingBuffersQueuedCount++;
934 mLastBracetingBufferIdx = nextBufferIdx;
935 setFrameRefCount((CameraBuffer *)imgCaptureData->mBufferHeader[nextBufferIdx]->pAppPrivate, typeOfFrame, 1);
936 returnFrame((CameraBuffer *)imgCaptureData->mBufferHeader[nextBufferIdx]->pAppPrivate, typeOfFrame);
937 }
938 }
939
940 LOG_FUNCTION_NAME_EXIT;
941
942 return ret;
943 }
944
sendBracketFrames(size_t & framesSent)945 status_t OMXCameraAdapter::sendBracketFrames(size_t &framesSent)
946 {
947 status_t ret = NO_ERROR;
948 int currentBufferIdx;
949 OMXCameraPortParameters * imgCaptureData = NULL;
950
951 LOG_FUNCTION_NAME;
952
953 imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
954 framesSent = 0;
955
956 if ( OMX_StateExecuting != mComponentState )
957 {
958 CAMHAL_LOGEA("OMX component is not in executing state");
959 ret = -EINVAL;
960 }
961
962 if ( NO_ERROR == ret )
963 {
964
965 currentBufferIdx = mLastBracetingBufferIdx;
966 do
967 {
968 currentBufferIdx++;
969 currentBufferIdx %= imgCaptureData->mNumBufs;
970 if (!mBracketingBuffersQueued[currentBufferIdx] )
971 {
972 CameraFrame cameraFrame;
973 sendCallBacks(cameraFrame,
974 imgCaptureData->mBufferHeader[currentBufferIdx],
975 imgCaptureData->mImageType,
976 imgCaptureData);
977 framesSent++;
978 }
979 } while ( currentBufferIdx != mLastBracetingBufferIdx );
980
981 }
982
983 LOG_FUNCTION_NAME_EXIT;
984
985 return ret;
986 }
987
startBracketing(int range)988 status_t OMXCameraAdapter::startBracketing(int range)
989 {
990 status_t ret = NO_ERROR;
991 OMXCameraPortParameters * imgCaptureData = NULL;
992
993 LOG_FUNCTION_NAME;
994
995 imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
996
997 if ( OMX_StateExecuting != mComponentState )
998 {
999 CAMHAL_LOGEA("OMX component is not in executing state");
1000 ret = -EINVAL;
1001 }
1002
1003 {
1004 android::AutoMutex lock(mBracketingLock);
1005
1006 if ( mBracketingEnabled )
1007 {
1008 return ret;
1009 }
1010 }
1011
1012 if ( 0 == imgCaptureData->mNumBufs )
1013 {
1014 CAMHAL_LOGEB("Image capture buffers set to %d", imgCaptureData->mNumBufs);
1015 ret = -EINVAL;
1016 }
1017
1018 if ( mPending3Asettings )
1019 apply3Asettings(mParameters3A);
1020
1021 if ( NO_ERROR == ret )
1022 {
1023 android::AutoMutex lock(mBracketingLock);
1024
1025 mBracketingRange = range;
1026 mBracketingBuffersQueued = new bool[imgCaptureData->mNumBufs];
1027 if ( NULL == mBracketingBuffersQueued )
1028 {
1029 CAMHAL_LOGEA("Unable to allocate bracketing management structures");
1030 ret = -1;
1031 }
1032
1033 if ( NO_ERROR == ret )
1034 {
1035 mBracketingBuffersQueuedCount = imgCaptureData->mNumBufs;
1036 mBurstFramesAccum = imgCaptureData->mNumBufs;
1037 mLastBracetingBufferIdx = mBracketingBuffersQueuedCount - 1;
1038
1039 for ( int i = 0 ; i < imgCaptureData->mNumBufs ; i++ )
1040 {
1041 mBracketingBuffersQueued[i] = true;
1042 }
1043
1044 }
1045 }
1046
1047 if ( NO_ERROR == ret )
1048 {
1049 CachedCaptureParameters* cap_params = cacheCaptureParameters();
1050 ret = startImageCapture(true, cap_params);
1051 delete cap_params;
1052 {
1053 android::AutoMutex lock(mBracketingLock);
1054
1055 if ( NO_ERROR == ret )
1056 {
1057 mBracketingEnabled = true;
1058 }
1059 else
1060 {
1061 mBracketingEnabled = false;
1062 }
1063 }
1064 }
1065
1066 LOG_FUNCTION_NAME_EXIT;
1067
1068 return ret;
1069 }
1070
stopBracketing()1071 status_t OMXCameraAdapter::stopBracketing()
1072 {
1073 status_t ret = NO_ERROR;
1074
1075 LOG_FUNCTION_NAME;
1076
1077 ret = stopImageCapture();
1078
1079 android::AutoMutex lock(mBracketingLock);
1080
1081 if ( NULL != mBracketingBuffersQueued )
1082 {
1083 delete [] mBracketingBuffersQueued;
1084 }
1085
1086 mBracketingBuffersQueued = NULL;
1087 mBracketingEnabled = false;
1088 mBracketingBuffersQueuedCount = 0;
1089 mLastBracetingBufferIdx = 0;
1090
1091 LOG_FUNCTION_NAME_EXIT;
1092
1093 return ret;
1094 }
1095
startImageCapture(bool bracketing,CachedCaptureParameters * capParams)1096 status_t OMXCameraAdapter::startImageCapture(bool bracketing, CachedCaptureParameters* capParams)
1097 {
1098 status_t ret = NO_ERROR;
1099 OMX_ERRORTYPE eError = OMX_ErrorNone;
1100 OMXCameraPortParameters * capData = NULL;
1101 OMX_CONFIG_BOOLEANTYPE bOMX;
1102 size_t bracketingSent = 0;
1103
1104 LOG_FUNCTION_NAME;
1105
1106 android::AutoMutex lock(mImageCaptureLock);
1107
1108 if(!mCaptureConfigured)
1109 {
1110 ///Image capture was cancelled before we could start
1111 return NO_ERROR;
1112 }
1113
1114 if ( 0 != mStartCaptureSem.Count() )
1115 {
1116 CAMHAL_LOGEB("Error mStartCaptureSem semaphore count %d", mStartCaptureSem.Count());
1117 return NO_INIT;
1118 }
1119
1120 if ( !bracketing ) {
1121 if ((getNextState() & (CAPTURE_ACTIVE|BRACKETING_ACTIVE)) == 0) {
1122 CAMHAL_LOGDA("trying starting capture when already canceled");
1123 return NO_ERROR;
1124 }
1125 }
1126
1127 if (!capParams) {
1128 CAMHAL_LOGE("Invalid cached parameters sent!");
1129 return BAD_VALUE;
1130 }
1131
1132 // Camera framework doesn't expect face callbacks once capture is triggered
1133 pauseFaceDetection(true);
1134
1135 //During bracketing image capture is already active
1136 {
1137 android::AutoMutex lock(mBracketingLock);
1138 if ( mBracketingEnabled )
1139 {
1140 //Stop bracketing, activate normal burst for the remaining images
1141 mBracketingEnabled = false;
1142 ret = sendBracketFrames(bracketingSent);
1143
1144 // Check if we accumulated enough buffers
1145 if ( bracketingSent < ( mBracketingRange - 1 ) )
1146 {
1147 mCapturedFrames = mBracketingRange + ( ( mBracketingRange - 1 ) - bracketingSent );
1148 }
1149 else
1150 {
1151 mCapturedFrames = mBracketingRange;
1152 }
1153 mBurstFramesQueued = 0;
1154 mBurstFramesAccum = mCapturedFrames;
1155
1156 if(ret != NO_ERROR)
1157 goto EXIT;
1158 else
1159 return ret;
1160 }
1161 }
1162
1163 if ( NO_ERROR == ret ) {
1164 if (capParams->mPendingCaptureSettings & SetRotation) {
1165 mPendingCaptureSettings &= ~SetRotation;
1166 ret = setPictureRotation(mPictureRotation);
1167 if ( NO_ERROR != ret ) {
1168 CAMHAL_LOGEB("Error configuring image rotation %x", ret);
1169 }
1170 }
1171
1172 if (capParams->mPendingCaptureSettings & SetBurstExpBracket) {
1173 mPendingCaptureSettings &= ~SetBurstExpBracket;
1174 if ( mBracketingSet ) {
1175 ret = doExposureBracketing(capParams->mExposureBracketingValues,
1176 capParams->mExposureGainBracketingValues,
1177 capParams->mExposureGainBracketingModes,
1178 0,
1179 0,
1180 capParams->mFlushShotConfigQueue,
1181 capParams->mExposureBracketMode);
1182 } else {
1183 ret = doExposureBracketing(capParams->mExposureBracketingValues,
1184 capParams->mExposureGainBracketingValues,
1185 capParams->mExposureGainBracketingModes,
1186 capParams->mExposureBracketingValidEntries,
1187 capParams->mBurstFrames,
1188 capParams->mFlushShotConfigQueue,
1189 capParams->mExposureBracketMode);
1190 }
1191
1192 if ( ret != NO_ERROR ) {
1193 CAMHAL_LOGEB("setExposureBracketing() failed %d", ret);
1194 goto EXIT;
1195 }
1196 }
1197 }
1198
1199 #if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
1200 CameraHal::PPM("startImageCapture bracketing configs done: ", &mStartCapture);
1201 #endif
1202
1203 capData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
1204
1205 //OMX shutter callback events are only available in hq mode
1206 if ( (HIGH_QUALITY == mCapMode) || (HIGH_QUALITY_ZSL== mCapMode)) {
1207 if ( NO_ERROR == ret )
1208 {
1209 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
1210 (OMX_EVENTTYPE) OMX_EventIndexSettingChanged,
1211 OMX_ALL,
1212 OMX_TI_IndexConfigShutterCallback,
1213 mStartCaptureSem);
1214 }
1215
1216 if ( NO_ERROR == ret )
1217 {
1218 ret = setShutterCallback(true);
1219 }
1220
1221 }
1222
1223 if (mPending3Asettings) {
1224 apply3Asettings(mParameters3A);
1225 }
1226
1227 if (ret == NO_ERROR) {
1228 int index = 0;
1229 int queued = 0;
1230 android::AutoMutex lock(mBurstLock);
1231
1232 if (capParams->mFlushShotConfigQueue) {
1233 // reset shot queue
1234 mCapturedFrames = mBurstFrames;
1235 mBurstFramesAccum = mBurstFrames;
1236 mBurstFramesQueued = 0;
1237 for ( int index = 0 ; index < capData->mNumBufs ; index++ ) {
1238 if (OMXCameraPortParameters::FILL == capData->mStatus[index]) {
1239 mBurstFramesQueued++;
1240 }
1241 }
1242 } else {
1243 mCapturedFrames += mBurstFrames;
1244 mBurstFramesAccum += mBurstFrames;
1245 }
1246 CAMHAL_LOGD("mBurstFramesQueued = %d mBurstFramesAccum = %d index = %d "
1247 "capData->mNumBufs = %d queued = %d capData->mMaxQueueable = %d",
1248 mBurstFramesQueued,mBurstFramesAccum,index,
1249 capData->mNumBufs,queued,capData->mMaxQueueable);
1250 CAMHAL_LOGD("%d", (mBurstFramesQueued < mBurstFramesAccum)
1251 && (index < capData->mNumBufs)
1252 && (queued < capData->mMaxQueueable));
1253 while ((mBurstFramesQueued < mBurstFramesAccum) &&
1254 (index < capData->mNumBufs) &&
1255 (queued < capData->mMaxQueueable)) {
1256 if (capData->mStatus[index] == OMXCameraPortParameters::IDLE) {
1257 CAMHAL_LOGDB("Queuing buffer on Capture port - %p",
1258 capData->mBufferHeader[index]->pBuffer);
1259 capData->mStatus[index] = OMXCameraPortParameters::FILL;
1260 eError = OMX_FillThisBuffer(mCameraAdapterParameters.mHandleComp,
1261 (OMX_BUFFERHEADERTYPE*)capData->mBufferHeader[index]);
1262 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1263 mBurstFramesQueued++;
1264 queued++;
1265 } else if (OMXCameraPortParameters::FILL == capData->mStatus[index]) {
1266 CAMHAL_LOGE("Not queueing index = %d", index);
1267 queued++;
1268 }
1269 index++;
1270 }
1271
1272 #ifdef CAMERAHAL_USE_RAW_IMAGE_SAVING
1273 if (mRawCapture) {
1274 capData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoPortIndex];
1275
1276 ///Queue all the buffers on capture port
1277 for ( int index = 0 ; index < capData->mNumBufs ; index++ ) {
1278 CAMHAL_LOGDB("Queuing buffer on Video port (for RAW capture) - 0x%x", ( unsigned int ) capData->mBufferHeader[index]->pBuffer);
1279 capData->mStatus[index] = OMXCameraPortParameters::FILL;
1280 eError = OMX_FillThisBuffer(mCameraAdapterParameters.mHandleComp,
1281 (OMX_BUFFERHEADERTYPE*)capData->mBufferHeader[index]);
1282
1283 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1284 }
1285 }
1286 #endif
1287
1288 mWaitingForSnapshot = true;
1289 mCaptureSignalled = false;
1290
1291 // Capturing command is not needed when capturing in video mode
1292 // Only need to queue buffers on image ports
1293 if ( ( mCapMode != VIDEO_MODE ) && ( mCapMode != VIDEO_MODE_HQ ) ) {
1294 OMX_INIT_STRUCT_PTR (&bOMX, OMX_CONFIG_BOOLEANTYPE);
1295 bOMX.bEnabled = OMX_TRUE;
1296
1297 /// sending Capturing Command to the component
1298 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
1299 OMX_IndexConfigCapturing,
1300 &bOMX);
1301
1302 CAMHAL_LOGDB("Capture set - 0x%x", eError);
1303
1304 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1305 }
1306 }
1307
1308 #if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
1309 CameraHal::PPM("startImageCapture image buffers queued and capture enabled: ", &mStartCapture);
1310 #endif
1311
1312 //OMX shutter callback events are only available in hq mode
1313
1314 if ( (HIGH_QUALITY == mCapMode) || (HIGH_QUALITY_ZSL== mCapMode))
1315 {
1316 if ( NO_ERROR == ret )
1317 {
1318 ret = mStartCaptureSem.WaitTimeout(OMX_CAPTURE_TIMEOUT);
1319 }
1320
1321 //If something bad happened while we wait
1322 if (mComponentState != OMX_StateExecuting)
1323 {
1324 CAMHAL_LOGEA("Invalid State after Image Capture Exitting!!!");
1325 goto EXIT;
1326 }
1327
1328 if ( NO_ERROR == ret )
1329 {
1330 CAMHAL_LOGDA("Shutter callback received");
1331 notifyShutterSubscribers();
1332 }
1333 else
1334 {
1335 ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
1336 (OMX_EVENTTYPE) OMX_EventIndexSettingChanged,
1337 OMX_ALL,
1338 OMX_TI_IndexConfigShutterCallback,
1339 NULL);
1340 CAMHAL_LOGEA("Timeout expired on shutter callback");
1341 goto EXIT;
1342 }
1343
1344 }
1345
1346 #if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
1347 CameraHal::PPM("startImageCapture shutter event received: ", &mStartCapture);
1348 #endif
1349
1350 return (ret | Utils::ErrorUtils::omxToAndroidError(eError));
1351
1352 EXIT:
1353 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
1354 mWaitingForSnapshot = false;
1355 mCaptureSignalled = false;
1356 performCleanupAfterError();
1357 LOG_FUNCTION_NAME_EXIT;
1358 return (ret | Utils::ErrorUtils::omxToAndroidError(eError));
1359 }
1360
stopImageCapture()1361 status_t OMXCameraAdapter::stopImageCapture()
1362 {
1363 status_t ret = NO_ERROR;
1364 OMX_ERRORTYPE eError = OMX_ErrorNone;
1365 OMX_CONFIG_BOOLEANTYPE bOMX;
1366 OMXCameraPortParameters *imgCaptureData = NULL;
1367
1368 LOG_FUNCTION_NAME;
1369
1370 android::AutoMutex lock(mImageCaptureLock);
1371
1372 if (!mCaptureConfigured) {
1373 //Capture is not ongoing, return from here
1374 return NO_ERROR;
1375 }
1376
1377 if ( 0 != mStopCaptureSem.Count() ) {
1378 CAMHAL_LOGEB("Error mStopCaptureSem semaphore count %d", mStopCaptureSem.Count());
1379 goto EXIT;
1380 }
1381
1382 // TODO(XXX): Reprocessing is currently piggy-backing capture commands
1383 if (mAdapterState == REPROCESS_STATE) {
1384 ret = stopReprocess();
1385 }
1386
1387 //Disable the callback first
1388 mWaitingForSnapshot = false;
1389
1390 // OMX shutter callback events are only available in hq mode
1391 if ((HIGH_QUALITY == mCapMode) || (HIGH_QUALITY_ZSL== mCapMode)) {
1392 //Disable the callback first
1393 ret = setShutterCallback(false);
1394
1395 // if anybody is waiting on the shutter callback
1396 // signal them and then recreate the semaphore
1397 if ( 0 != mStartCaptureSem.Count() ) {
1398
1399 for (int i = mStartCaptureSem.Count(); i < 0; i++) {
1400 ret |= SignalEvent(mCameraAdapterParameters.mHandleComp,
1401 (OMX_EVENTTYPE) OMX_EventIndexSettingChanged,
1402 OMX_ALL,
1403 OMX_TI_IndexConfigShutterCallback,
1404 NULL );
1405 }
1406 mStartCaptureSem.Create(0);
1407 }
1408 } else if (CP_CAM == mCapMode) {
1409 // Reset shot config queue
1410 OMX_TI_CONFIG_ENQUEUESHOTCONFIGS resetShotConfigs;
1411 OMX_INIT_STRUCT_PTR(&resetShotConfigs, OMX_TI_CONFIG_ENQUEUESHOTCONFIGS);
1412
1413 resetShotConfigs.nPortIndex = mCameraAdapterParameters.mImagePortIndex;
1414 resetShotConfigs.bFlushQueue = OMX_TRUE;
1415 resetShotConfigs.nNumConfigs = 0;
1416 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
1417 ( OMX_INDEXTYPE ) OMX_TI_IndexConfigEnqueueShotConfigs,
1418 &resetShotConfigs);
1419 if ( OMX_ErrorNone != eError ) {
1420 CAMHAL_LOGEB("Error while reset shot config 0x%x", eError);
1421 goto EXIT;
1422 } else {
1423 CAMHAL_LOGDA("Shot config reset successfully");
1424 }
1425 }
1426
1427 //Wait here for the capture to be done, in worst case timeout and proceed with cleanup
1428 mCaptureSem.WaitTimeout(OMX_CAPTURE_TIMEOUT);
1429
1430 //If somethiing bad happened while we wait
1431 if (mComponentState == OMX_StateInvalid)
1432 {
1433 CAMHAL_LOGEA("Invalid State Image Capture Stop Exitting!!!");
1434 goto EXIT;
1435 }
1436
1437 // Disable image capture
1438 // Capturing command is not needed when capturing in video mode
1439 if ( ( mCapMode != VIDEO_MODE ) && ( mCapMode != VIDEO_MODE_HQ ) ) {
1440 OMX_INIT_STRUCT_PTR (&bOMX, OMX_CONFIG_BOOLEANTYPE);
1441 bOMX.bEnabled = OMX_FALSE;
1442 imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
1443 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
1444 OMX_IndexConfigCapturing,
1445 &bOMX);
1446 if ( OMX_ErrorNone != eError ) {
1447 CAMHAL_LOGDB("Error during SetConfig- 0x%x", eError);
1448 ret = -1;
1449 goto EXIT;
1450 }
1451 }
1452
1453 CAMHAL_LOGDB("Capture set - 0x%x", eError);
1454
1455 mCaptureSignalled = true; //set this to true if we exited because of timeout
1456
1457 {
1458 android::AutoMutex lock(mFrameCountMutex);
1459 mFrameCount = 0;
1460 mFirstFrameCondition.broadcast();
1461 }
1462
1463 // Stop is always signalled externally in CPCAM mode
1464 // We need to make sure we really stop
1465 if ((mCapMode == CP_CAM)) {
1466 disableReprocess();
1467 disableImagePort();
1468 if ( NULL != mReleaseImageBuffersCallback ) {
1469 mReleaseImageBuffersCallback(mReleaseData);
1470 }
1471 }
1472
1473 // Moving code for below commit here as an optimization for continuous capture,
1474 // so focus settings don't have to reapplied after each capture
1475 // c78fa2a CameraHAL: Always reset focus mode after capture
1476 // Workaround when doing many consecutive shots, CAF wasn't getting restarted.
1477 mPending3Asettings |= SetFocus;
1478
1479 mCapturedFrames = 0;
1480 mBurstFramesAccum = 0;
1481 mBurstFramesQueued = 0;
1482
1483 return (ret | Utils::ErrorUtils::omxToAndroidError(eError));
1484
1485 EXIT:
1486 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
1487 //Release image buffers
1488 if ( NULL != mReleaseImageBuffersCallback ) {
1489 mReleaseImageBuffersCallback(mReleaseData);
1490 }
1491
1492 {
1493 android::AutoMutex lock(mFrameCountMutex);
1494 mFrameCount = 0;
1495 mFirstFrameCondition.broadcast();
1496 }
1497
1498 performCleanupAfterError();
1499 LOG_FUNCTION_NAME_EXIT;
1500 return (ret | Utils::ErrorUtils::omxToAndroidError(eError));
1501 }
1502
disableImagePort()1503 status_t OMXCameraAdapter::disableImagePort(){
1504 status_t ret = NO_ERROR;
1505 OMX_ERRORTYPE eError = OMX_ErrorNone;
1506 OMXCameraPortParameters *imgCaptureData = NULL;
1507 OMXCameraPortParameters *imgRawCaptureData = NULL;
1508
1509 if (!mCaptureConfigured) {
1510 return NO_ERROR;
1511 }
1512
1513 mCaptureConfigured = false;
1514 imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
1515 imgRawCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoPortIndex]; // for RAW capture
1516
1517 ///Register for Image port Disable event
1518 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
1519 OMX_EventCmdComplete,
1520 OMX_CommandPortDisable,
1521 mCameraAdapterParameters.mImagePortIndex,
1522 mStopCaptureSem);
1523 ///Disable Capture Port
1524 eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
1525 OMX_CommandPortDisable,
1526 mCameraAdapterParameters.mImagePortIndex,
1527 NULL);
1528
1529 ///Free all the buffers on capture port
1530 if (imgCaptureData) {
1531 CAMHAL_LOGDB("Freeing buffer on Capture port - %d", imgCaptureData->mNumBufs);
1532 for ( int index = 0 ; index < imgCaptureData->mNumBufs ; index++) {
1533 CAMHAL_LOGDB("Freeing buffer on Capture port - 0x%x",
1534 ( unsigned int ) imgCaptureData->mBufferHeader[index]->pBuffer);
1535 eError = OMX_FreeBuffer(mCameraAdapterParameters.mHandleComp,
1536 mCameraAdapterParameters.mImagePortIndex,
1537 (OMX_BUFFERHEADERTYPE*)imgCaptureData->mBufferHeader[index]);
1538
1539 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1540 }
1541 }
1542 CAMHAL_LOGDA("Waiting for port disable");
1543 //Wait for the image port enable event
1544 ret = mStopCaptureSem.WaitTimeout(OMX_CMD_TIMEOUT);
1545
1546 //If somethiing bad happened while we wait
1547 if (mComponentState == OMX_StateInvalid)
1548 {
1549 CAMHAL_LOGEA("Invalid State after Disable Image Port Exitting!!!");
1550 goto EXIT;
1551 }
1552
1553 if ( NO_ERROR == ret ) {
1554 CAMHAL_LOGDA("Port disabled");
1555 } else {
1556 ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
1557 OMX_EventCmdComplete,
1558 OMX_CommandPortDisable,
1559 mCameraAdapterParameters.mImagePortIndex,
1560 NULL);
1561 CAMHAL_LOGDA("Timeout expired on port disable");
1562 goto EXIT;
1563 }
1564
1565 deinitInternalBuffers(mCameraAdapterParameters.mImagePortIndex);
1566
1567 // since port settings are not persistent after port is disabled...
1568 mPendingCaptureSettings |= SetFormat;
1569
1570 #ifdef CAMERAHAL_USE_RAW_IMAGE_SAVING
1571
1572 if (mRawCapture) {
1573 ///Register for Video port Disable event
1574 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
1575 OMX_EventCmdComplete,
1576 OMX_CommandPortDisable,
1577 mCameraAdapterParameters.mVideoPortIndex,
1578 mStopCaptureSem);
1579 ///Disable RawCapture Port
1580 eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
1581 OMX_CommandPortDisable,
1582 mCameraAdapterParameters.mVideoPortIndex,
1583 NULL);
1584
1585 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1586
1587 ///Free all the buffers on RawCapture port
1588 if (imgRawCaptureData) {
1589 CAMHAL_LOGDB("Freeing buffer on Capture port - %d", imgRawCaptureData->mNumBufs);
1590 for ( int index = 0 ; index < imgRawCaptureData->mNumBufs ; index++) {
1591 CAMHAL_LOGDB("Freeing buffer on Capture port - 0x%x", ( unsigned int ) imgRawCaptureData->mBufferHeader[index]->pBuffer);
1592 eError = OMX_FreeBuffer(mCameraAdapterParameters.mHandleComp,
1593 mCameraAdapterParameters.mVideoPortIndex,
1594 (OMX_BUFFERHEADERTYPE*)imgRawCaptureData->mBufferHeader[index]);
1595
1596 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1597 }
1598 }
1599 CAMHAL_LOGDA("Waiting for Video port disable");
1600 //Wait for the image port enable event
1601 mStopCaptureSem.WaitTimeout(OMX_CMD_TIMEOUT);
1602 CAMHAL_LOGDA("Video Port disabled");
1603 }
1604 #endif
1605
1606 EXIT:
1607 return (ret | Utils::ErrorUtils::omxToAndroidError(eError));
1608 }
1609
initInternalBuffers(OMX_U32 portIndex)1610 status_t OMXCameraAdapter::initInternalBuffers(OMX_U32 portIndex)
1611 {
1612 OMX_ERRORTYPE eError = OMX_ErrorNone;
1613 int index = 0;
1614 OMX_TI_PARAM_USEBUFFERDESCRIPTOR bufferdesc;
1615
1616 /* Indicate to Ducati that we're planning to use dynamically-mapped buffers */
1617 OMX_INIT_STRUCT_PTR (&bufferdesc, OMX_TI_PARAM_USEBUFFERDESCRIPTOR);
1618 bufferdesc.nPortIndex = portIndex;
1619 bufferdesc.bEnabled = OMX_FALSE;
1620 bufferdesc.eBufferType = OMX_TI_BufferTypePhysicalPageList;
1621
1622 eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp,
1623 (OMX_INDEXTYPE) OMX_TI_IndexUseBufferDescriptor,
1624 &bufferdesc);
1625 if (eError!=OMX_ErrorNone) {
1626 CAMHAL_LOGEB("OMX_SetParameter - %x", eError);
1627 return -EINVAL;
1628 }
1629
1630 CAMHAL_LOGDA("Initializing internal buffers");
1631 do {
1632 OMX_TI_PARAM_COMPONENTBUFALLOCTYPE bufferalloc;
1633 OMX_TI_PARAM_COMPONENTBUFALLOCTYPE bufferallocset;
1634 OMX_INIT_STRUCT_PTR (&bufferalloc, OMX_TI_PARAM_COMPONENTBUFALLOCTYPE);
1635 bufferalloc.nPortIndex = portIndex;
1636 bufferalloc.nIndex = index;
1637
1638 eError = OMX_GetParameter (mCameraAdapterParameters.mHandleComp,
1639 (OMX_INDEXTYPE)OMX_TI_IndexParamComponentBufferAllocation,
1640 &bufferalloc);
1641 if (eError == OMX_ErrorNoMore) {
1642 return NO_ERROR;
1643 }
1644 if (eError != OMX_ErrorNone) {
1645 CAMHAL_LOGE("GetParameter failed error = 0x%x", eError);
1646 break;
1647 }
1648
1649 CAMHAL_LOGDB("Requesting buftype %d of size %dx%d",
1650 (int)bufferalloc.eBufType, (int)bufferalloc.nAllocWidth,
1651 (int)bufferalloc.nAllocLines);
1652
1653 bufferalloc.eBufType = OMX_TI_BufferTypeHardwareReserved1D;
1654
1655 OMX_INIT_STRUCT_PTR (&bufferallocset, OMX_TI_PARAM_COMPONENTBUFALLOCTYPE);
1656 bufferallocset.nPortIndex = portIndex;
1657 bufferallocset.nIndex = index;
1658 bufferallocset.eBufType = OMX_TI_BufferTypeHardwareReserved1D;
1659 bufferallocset.nAllocWidth = bufferalloc.nAllocWidth;
1660 bufferallocset.nAllocLines = bufferalloc.nAllocLines;
1661
1662 eError = OMX_SetParameter (mCameraAdapterParameters.mHandleComp,
1663 (OMX_INDEXTYPE)OMX_TI_IndexParamComponentBufferAllocation,
1664 &bufferallocset);
1665 if (eError != OMX_ErrorNone) {
1666 CAMHAL_LOGE("SetParameter failed, error=%08x", eError);
1667 if (eError == OMX_ErrorNoMore) return NO_ERROR;
1668 break;
1669 }
1670
1671 index++;
1672
1673 /* 1 is an arbitrary limit */
1674 } while (index < 1);
1675
1676 CAMHAL_LOGV("Ducati requested too many (>1) internal buffers");
1677
1678 return -EINVAL;
1679 }
1680
deinitInternalBuffers(OMX_U32 portIndex)1681 status_t OMXCameraAdapter::deinitInternalBuffers(OMX_U32 portIndex)
1682 {
1683 OMX_ERRORTYPE eError = OMX_ErrorNone;
1684 OMX_TI_PARAM_USEBUFFERDESCRIPTOR bufferdesc;
1685
1686 OMX_INIT_STRUCT_PTR (&bufferdesc, OMX_TI_PARAM_USEBUFFERDESCRIPTOR);
1687 bufferdesc.nPortIndex = portIndex;
1688 bufferdesc.bEnabled = OMX_FALSE;
1689 bufferdesc.eBufferType = OMX_TI_BufferTypeDefault;
1690
1691 eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp,
1692 (OMX_INDEXTYPE) OMX_TI_IndexUseBufferDescriptor,
1693 &bufferdesc);
1694 if (eError!=OMX_ErrorNone) {
1695 CAMHAL_LOGEB("OMX_SetParameter - %x", eError);
1696 return -EINVAL;
1697 }
1698
1699 OMX_TI_PARAM_COMPONENTBUFALLOCTYPE bufferalloc;
1700 OMX_INIT_STRUCT_PTR (&bufferalloc, OMX_TI_PARAM_COMPONENTBUFALLOCTYPE);
1701 bufferalloc.nPortIndex = portIndex;
1702 bufferalloc.eBufType = OMX_TI_BufferTypeDefault;
1703 bufferalloc.nAllocWidth = 1;
1704 bufferalloc.nAllocLines = 1;
1705 eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp,
1706 (OMX_INDEXTYPE) OMX_TI_IndexParamComponentBufferAllocation,
1707 &bufferalloc);
1708 if (eError!=OMX_ErrorNone) {
1709 CAMHAL_LOGEB("OMX_SetParameter - %x", eError);
1710 return -EINVAL;
1711 }
1712
1713 return Utils::ErrorUtils::omxToAndroidError(eError);
1714 }
1715
UseBuffersCapture(CameraBuffer * bufArr,int num)1716 status_t OMXCameraAdapter::UseBuffersCapture(CameraBuffer * bufArr, int num)
1717 {
1718 LOG_FUNCTION_NAME;
1719
1720 status_t ret = NO_ERROR;
1721 OMX_ERRORTYPE eError = OMX_ErrorNone;
1722 OMXCameraPortParameters * imgCaptureData = NULL;
1723 OMXCameraPortParameters cap;
1724
1725 imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
1726
1727 if ( 0 != mUseCaptureSem.Count() )
1728 {
1729 CAMHAL_LOGEB("Error mUseCaptureSem semaphore count %d", mUseCaptureSem.Count());
1730 return BAD_VALUE;
1731 }
1732
1733 CAMHAL_ASSERT(num > 0);
1734
1735 // if some setting that requires a SetParameter (including
1736 // changing buffer types) then we need to disable the port
1737 // before being allowed to apply the settings
1738 if ((mPendingCaptureSettings & ECaptureParamSettings) ||
1739 bufArr[0].type != imgCaptureData->mBufferType ||
1740 imgCaptureData->mNumBufs != num) {
1741 if (mCaptureConfigured) {
1742 disableImagePort();
1743 if ( NULL != mReleaseImageBuffersCallback ) {
1744 mReleaseImageBuffersCallback(mReleaseData);
1745 }
1746 }
1747
1748 imgCaptureData->mBufferType = bufArr[0].type;
1749 imgCaptureData->mNumBufs = num;
1750
1751 CAMHAL_LOGDB("Params Width = %d", (int)imgCaptureData->mWidth);
1752 CAMHAL_LOGDB("Params Height = %d", (int)imgCaptureData->mHeight);
1753
1754 if (mPendingCaptureSettings & SetFormat) {
1755 mPendingCaptureSettings &= ~SetFormat;
1756 ret = setFormat(OMX_CAMERA_PORT_IMAGE_OUT_IMAGE, *imgCaptureData);
1757 if ( ret != NO_ERROR ) {
1758 CAMHAL_LOGEB("setFormat() failed %d", ret);
1759 LOG_FUNCTION_NAME_EXIT;
1760 return ret;
1761 }
1762 }
1763
1764 if (mPendingCaptureSettings & SetThumb) {
1765 mPendingCaptureSettings &= ~SetThumb;
1766 ret = setThumbnailParams(mThumbWidth, mThumbHeight, mThumbQuality);
1767 if ( NO_ERROR != ret) {
1768 CAMHAL_LOGEB("Error configuring thumbnail size %x", ret);
1769 return ret;
1770 }
1771 }
1772
1773 if (mPendingCaptureSettings & SetQuality) {
1774 mPendingCaptureSettings &= ~SetQuality;
1775 ret = setImageQuality(mPictureQuality);
1776 if ( NO_ERROR != ret) {
1777 CAMHAL_LOGEB("Error configuring image quality %x", ret);
1778 goto EXIT;
1779 }
1780 }
1781
1782 // Configure DOMX to use either gralloc handles or vptrs
1783 {
1784 OMX_TI_PARAMUSENATIVEBUFFER domxUseGrallocHandles;
1785 OMX_INIT_STRUCT_PTR (&domxUseGrallocHandles, OMX_TI_PARAMUSENATIVEBUFFER);
1786
1787 domxUseGrallocHandles.nPortIndex = mCameraAdapterParameters.mImagePortIndex;
1788 if (bufArr[0].type == CAMERA_BUFFER_ANW) {
1789 CAMHAL_LOGD ("Using ANW Buffers");
1790 initInternalBuffers(mCameraAdapterParameters.mImagePortIndex);
1791 domxUseGrallocHandles.bEnable = OMX_TRUE;
1792 } else {
1793 CAMHAL_LOGD ("Using ION Buffers");
1794 domxUseGrallocHandles.bEnable = OMX_FALSE;
1795 }
1796
1797 eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp,
1798 (OMX_INDEXTYPE)OMX_TI_IndexUseNativeBuffers, &domxUseGrallocHandles);
1799 if (eError!=OMX_ErrorNone) {
1800 CAMHAL_LOGEB("OMX_SetParameter - %x", eError);
1801 }
1802 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1803 }
1804
1805 #if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
1806
1807 CameraHal::PPM("Takepicture image port configuration: ", &bufArr->ppmStamp);
1808
1809 #endif
1810
1811 // Register for Image port ENABLE event
1812 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
1813 OMX_EventCmdComplete,
1814 OMX_CommandPortEnable,
1815 mCameraAdapterParameters.mImagePortIndex,
1816 mUseCaptureSem);
1817
1818 // Enable Capture Port
1819 eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
1820 OMX_CommandPortEnable,
1821 mCameraAdapterParameters.mImagePortIndex,
1822 NULL);
1823
1824 CAMHAL_LOGDB("OMX_UseBuffer = 0x%x", eError);
1825 GOTO_EXIT_IF(( eError != OMX_ErrorNone ), eError);
1826
1827 for (int index = 0 ; index < imgCaptureData->mNumBufs ; index++) {
1828 OMX_BUFFERHEADERTYPE *pBufferHdr;
1829 CAMHAL_LOGDB("OMX_UseBuffer Capture address: 0x%x, size = %d",
1830 (unsigned int)bufArr[index].opaque,
1831 (int)imgCaptureData->mBufSize);
1832
1833 eError = OMX_UseBuffer(mCameraAdapterParameters.mHandleComp,
1834 &pBufferHdr,
1835 mCameraAdapterParameters.mImagePortIndex,
1836 0,
1837 imgCaptureData->mBufSize,
1838 (OMX_U8*)camera_buffer_get_omx_ptr(&bufArr[index]));
1839
1840 CAMHAL_LOGDB("OMX_UseBuffer = 0x%x", eError);
1841 GOTO_EXIT_IF(( eError != OMX_ErrorNone ), eError);
1842
1843 pBufferHdr->pAppPrivate = (OMX_PTR) &bufArr[index];
1844 bufArr[index].index = index;
1845 pBufferHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
1846 pBufferHdr->nVersion.s.nVersionMajor = 1 ;
1847 pBufferHdr->nVersion.s.nVersionMinor = 1 ;
1848 pBufferHdr->nVersion.s.nRevision = 0;
1849 pBufferHdr->nVersion.s.nStep = 0;
1850 imgCaptureData->mBufferHeader[index] = pBufferHdr;
1851 imgCaptureData->mStatus[index] = OMXCameraPortParameters::IDLE;
1852 }
1853
1854 // Wait for the image port enable event
1855 CAMHAL_LOGDA("Waiting for port enable");
1856 ret = mUseCaptureSem.WaitTimeout(OMX_CMD_TIMEOUT);
1857
1858 // If somethiing bad happened while we wait
1859 if (mComponentState == OMX_StateInvalid) {
1860 CAMHAL_LOGEA("Invalid State after Enable Image Port Exitting!!!");
1861 goto EXIT;
1862 }
1863
1864 if (ret != NO_ERROR) {
1865 ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
1866 OMX_EventCmdComplete,
1867 OMX_CommandPortEnable,
1868 mCameraAdapterParameters.mImagePortIndex,
1869 NULL);
1870 CAMHAL_LOGDA("Timeout expired on port enable");
1871 goto EXIT;
1872 }
1873 CAMHAL_LOGDA("Port enabled");
1874
1875 #if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
1876
1877 CameraHal::PPM("Takepicture image port enabled and buffers registered: ", &bufArr->ppmStamp);
1878
1879 #endif
1880
1881 if (mNextState != LOADED_REPROCESS_CAPTURE_STATE) {
1882 // Enable WB and vector shot extra data for metadata
1883 setExtraData(true, mCameraAdapterParameters.mImagePortIndex, OMX_WhiteBalance);
1884 setExtraData(true, mCameraAdapterParameters.mImagePortIndex, OMX_TI_LSCTable);
1885 }
1886
1887 // CPCam mode only supports vector shot
1888 // Regular capture is not supported
1889 if ( (mCapMode == CP_CAM) && (mNextState != LOADED_REPROCESS_CAPTURE_STATE) ) {
1890 initVectorShot();
1891 }
1892
1893 mCaptureBuffersAvailable.clear();
1894 for (unsigned int i = 0; i < imgCaptureData->mMaxQueueable; i++ ) {
1895 mCaptureBuffersAvailable.add(&mCaptureBuffers[i], 0);
1896 }
1897
1898 // initial ref count for undeqeueued buffers is 1 since buffer provider
1899 // is still holding on to it
1900 for (unsigned int i = imgCaptureData->mMaxQueueable; i < imgCaptureData->mNumBufs; i++ ) {
1901 mCaptureBuffersAvailable.add(&mCaptureBuffers[i], 1);
1902 }
1903 }
1904
1905 if ( NO_ERROR == ret )
1906 {
1907 ret = setupEXIF();
1908 if ( NO_ERROR != ret )
1909 {
1910 CAMHAL_LOGEB("Error configuring EXIF Buffer %x", ret);
1911 }
1912 }
1913
1914 // Choose proper single preview mode for cp capture (reproc or hs)
1915 if (( NO_ERROR == ret) && (OMXCameraAdapter::CP_CAM == mCapMode)) {
1916 OMX_TI_CONFIG_SINGLEPREVIEWMODETYPE singlePrevMode;
1917 OMX_INIT_STRUCT_PTR (&singlePrevMode, OMX_TI_CONFIG_SINGLEPREVIEWMODETYPE);
1918 if (mNextState == LOADED_CAPTURE_STATE) {
1919 singlePrevMode.eMode = OMX_TI_SinglePreviewMode_ImageCaptureHighSpeed;
1920 } else if (mNextState == LOADED_REPROCESS_CAPTURE_STATE) {
1921 singlePrevMode.eMode = OMX_TI_SinglePreviewMode_Reprocess;
1922 } else {
1923 CAMHAL_LOGE("Wrong state trying to start a capture in CPCAM mode?");
1924 singlePrevMode.eMode = OMX_TI_SinglePreviewMode_ImageCaptureHighSpeed;
1925 }
1926 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
1927 (OMX_INDEXTYPE) OMX_TI_IndexConfigSinglePreviewMode,
1928 &singlePrevMode);
1929 if ( OMX_ErrorNone != eError ) {
1930 CAMHAL_LOGEB("Error while configuring single preview mode 0x%x", eError);
1931 ret = Utils::ErrorUtils::omxToAndroidError(eError);
1932 } else {
1933 CAMHAL_LOGDA("single preview mode configured successfully");
1934 }
1935 }
1936
1937 #if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
1938
1939 CameraHal::PPM("Takepicture extra configs on image port done: ", &bufArr->ppmStamp);
1940
1941 #endif
1942
1943 mCaptureConfigured = true;
1944
1945 #ifdef CAMERAHAL_USE_RAW_IMAGE_SAVING
1946 if (mRawCapture) {
1947 mCaptureConfigured = false;
1948 }
1949 #endif
1950
1951 return (ret | Utils::ErrorUtils::omxToAndroidError(eError));
1952
1953 EXIT:
1954 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
1955 setExtraData(false, mCameraAdapterParameters.mImagePortIndex, OMX_WhiteBalance);
1956 // TODO: WA: if domx client disables VectShotInfo metadata on the image port, this causes
1957 // VectShotInfo to be disabled internally on preview port also. Remove setting in OMXCapture
1958 // setExtraData(false, mCameraAdapterParameters.mImagePortIndex, OMX_TI_VectShotInfo);
1959 setExtraData(false, mCameraAdapterParameters.mImagePortIndex, OMX_TI_LSCTable);
1960 //Release image buffers
1961 if ( NULL != mReleaseImageBuffersCallback ) {
1962 mReleaseImageBuffersCallback(mReleaseData);
1963 }
1964 performCleanupAfterError();
1965 LOG_FUNCTION_NAME_EXIT;
1966 return (ret | Utils::ErrorUtils::omxToAndroidError(eError));
1967
1968 }
UseBuffersRawCapture(CameraBuffer * bufArr,int num)1969 status_t OMXCameraAdapter::UseBuffersRawCapture(CameraBuffer *bufArr, int num)
1970 {
1971 LOG_FUNCTION_NAME
1972 status_t ret;
1973 OMX_ERRORTYPE eError;
1974 OMXCameraPortParameters * imgRawCaptureData = NULL;
1975 Utils::Semaphore camSem;
1976 OMXCameraPortParameters cap;
1977
1978 imgRawCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoPortIndex];
1979
1980 if (mCaptureConfigured) {
1981 return NO_ERROR;
1982 }
1983
1984 camSem.Create();
1985
1986 // mWaitingForSnapshot is true only when we're in the process of capturing
1987 if (mWaitingForSnapshot) {
1988 ///Register for Video port Disable event
1989 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
1990 (OMX_EVENTTYPE) OMX_EventCmdComplete,
1991 OMX_CommandPortDisable,
1992 mCameraAdapterParameters.mVideoPortIndex,
1993 camSem);
1994
1995 ///Disable Capture Port
1996 eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
1997 OMX_CommandPortDisable,
1998 mCameraAdapterParameters.mVideoPortIndex,
1999 NULL);
2000
2001 CAMHAL_LOGDA("Waiting for port disable");
2002 //Wait for the image port enable event
2003 camSem.Wait();
2004 CAMHAL_LOGDA("Port disabled");
2005 }
2006
2007 imgRawCaptureData->mNumBufs = num;
2008
2009 CAMHAL_LOGDB("RAW Max sensor width = %d", (int)imgRawCaptureData->mWidth);
2010 CAMHAL_LOGDB("RAW Max sensor height = %d", (int)imgRawCaptureData->mHeight);
2011
2012 ret = setFormat(OMX_CAMERA_PORT_VIDEO_OUT_VIDEO, *imgRawCaptureData);
2013
2014 if (ret != NO_ERROR) {
2015 CAMHAL_LOGEB("setFormat() failed %d", ret);
2016 LOG_FUNCTION_NAME_EXIT
2017 return ret;
2018 }
2019
2020 ///Register for Video port ENABLE event
2021 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
2022 (OMX_EVENTTYPE) OMX_EventCmdComplete,
2023 OMX_CommandPortEnable,
2024 mCameraAdapterParameters.mVideoPortIndex,
2025 camSem);
2026
2027 ///Enable Video Capture Port
2028 eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
2029 OMX_CommandPortEnable,
2030 mCameraAdapterParameters.mVideoPortIndex,
2031 NULL);
2032
2033 mCaptureBuffersLength = (int)imgRawCaptureData->mBufSize;
2034 for ( int index = 0 ; index < imgRawCaptureData->mNumBufs ; index++ ) {
2035 OMX_BUFFERHEADERTYPE *pBufferHdr;
2036 CAMHAL_LOGDB("OMX_UseBuffer rawCapture address: 0x%x, size = %d ",
2037 (unsigned int)bufArr[index].opaque,
2038 (int)imgRawCaptureData->mBufSize );
2039
2040 eError = OMX_UseBuffer( mCameraAdapterParameters.mHandleComp,
2041 &pBufferHdr,
2042 mCameraAdapterParameters.mVideoPortIndex,
2043 0,
2044 mCaptureBuffersLength,
2045 (OMX_U8*)camera_buffer_get_omx_ptr(&bufArr[index]));
2046 if (eError != OMX_ErrorNone) {
2047 CAMHAL_LOGEB("OMX_UseBuffer = 0x%x", eError);
2048 }
2049
2050 GOTO_EXIT_IF(( eError != OMX_ErrorNone ), eError);
2051
2052 pBufferHdr->pAppPrivate = (OMX_PTR) &bufArr[index];
2053 bufArr[index].index = index;
2054 pBufferHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
2055 pBufferHdr->nVersion.s.nVersionMajor = 1 ;
2056 pBufferHdr->nVersion.s.nVersionMinor = 1 ;
2057 pBufferHdr->nVersion.s.nRevision = 0;
2058 pBufferHdr->nVersion.s.nStep = 0;
2059 imgRawCaptureData->mBufferHeader[index] = pBufferHdr;
2060
2061 }
2062
2063 //Wait for the image port enable event
2064 CAMHAL_LOGDA("Waiting for port enable");
2065 camSem.Wait();
2066 CAMHAL_LOGDA("Port enabled");
2067
2068 if (NO_ERROR == ret) {
2069 ret = setupEXIF();
2070 if ( NO_ERROR != ret ) {
2071 CAMHAL_LOGEB("Error configuring EXIF Buffer %x", ret);
2072 }
2073 }
2074
2075 mCapturedFrames = mBurstFrames;
2076 mBurstFramesQueued = 0;
2077 mCaptureConfigured = true;
2078
2079 EXIT:
2080
2081 if (eError != OMX_ErrorNone) {
2082 if ( NULL != mErrorNotifier )
2083 {
2084 mErrorNotifier->errorNotify(eError);
2085 }
2086 }
2087
2088 LOG_FUNCTION_NAME_EXIT
2089
2090 return ret;
2091 }
2092
2093 } // namespace Camera
2094 } // namespace Ti
2095