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 OMXCameraAdapter.cpp
19 *
20 * This file maps the Camera Hardware Interface to OMX.
21 *
22 */
23
24 #include "CameraHal.h"
25 #include "OMXCameraAdapter.h"
26 #include "ErrorUtils.h"
27 #include "TICameraParameters.h"
28 #include <signal.h>
29 #include <math.h>
30
31 #include <cutils/properties.h>
32 #define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
33 static int mDebugFps = 0;
34 static int mDebugFcs = 0;
35
36
37 #define HERE(Msg) {CAMHAL_LOGEB("--===line %d, %s===--\n", __LINE__, Msg);}
38
39 namespace android {
40
41 #undef LOG_TAG
42 ///Maintain a separate tag for OMXCameraAdapter logs to isolate issues OMX specific
43 #define LOG_TAG "CameraHAL"
44
45 //frames skipped before recalculating the framerate
46 #define FPS_PERIOD 30
47
48 Mutex gAdapterLock;
49 /*--------------------Camera Adapter Class STARTS here-----------------------------*/
50
initialize(CameraProperties::Properties * caps)51 status_t OMXCameraAdapter::initialize(CameraProperties::Properties* caps)
52 {
53 LOG_FUNCTION_NAME;
54
55 char value[PROPERTY_VALUE_MAX];
56 property_get("debug.camera.showfps", value, "0");
57 mDebugFps = atoi(value);
58 property_get("debug.camera.framecounts", value, "0");
59 mDebugFcs = atoi(value);
60
61 TIMM_OSAL_ERRORTYPE osalError = OMX_ErrorNone;
62 OMX_ERRORTYPE eError = OMX_ErrorNone;
63 status_t ret = NO_ERROR;
64
65
66 mLocalVersionParam.s.nVersionMajor = 0x1;
67 mLocalVersionParam.s.nVersionMinor = 0x1;
68 mLocalVersionParam.s.nRevision = 0x0 ;
69 mLocalVersionParam.s.nStep = 0x0;
70
71 mPending3Asettings = 0;//E3AsettingsAll;
72 mPendingCaptureSettings = 0;
73
74 if ( 0 != mInitSem.Count() )
75 {
76 CAMHAL_LOGEB("Error mInitSem semaphore count %d", mInitSem.Count());
77 LOG_FUNCTION_NAME_EXIT;
78 return NO_INIT;
79 }
80
81 if (mComponentState != OMX_StateLoaded && mComponentState != OMX_StateInvalid) {
82 CAMHAL_LOGEB("Error mComponentState %d is invalid!", mComponentState);
83 LOG_FUNCTION_NAME_EXIT;
84 return NO_INIT;
85 }
86
87 ///Update the preview and image capture port indexes
88 mCameraAdapterParameters.mPrevPortIndex = OMX_CAMERA_PORT_VIDEO_OUT_PREVIEW;
89 // temp changed in order to build OMX_CAMERA_PORT_VIDEO_OUT_IMAGE;
90 mCameraAdapterParameters.mImagePortIndex = OMX_CAMERA_PORT_IMAGE_OUT_IMAGE;
91 mCameraAdapterParameters.mMeasurementPortIndex = OMX_CAMERA_PORT_VIDEO_OUT_MEASUREMENT;
92 //currently not supported use preview port instead
93 mCameraAdapterParameters.mVideoPortIndex = OMX_CAMERA_PORT_VIDEO_OUT_PREVIEW;
94
95 eError = OMX_Init();
96 if (eError != OMX_ErrorNone) {
97 CAMHAL_LOGEB("Error OMX_Init -0x%x", eError);
98 return eError;
99 }
100
101 ///Get the handle to the OMX Component
102 eError = OMXCameraAdapter::OMXCameraGetHandle(&mCameraAdapterParameters.mHandleComp, (OMX_PTR)this);
103 if(eError != OMX_ErrorNone) {
104 CAMHAL_LOGEB("OMX_GetHandle -0x%x", eError);
105 }
106 GOTO_EXIT_IF((eError != OMX_ErrorNone), eError);
107
108 CAMHAL_LOGVB("OMX_GetHandle -0x%x sensor_index = %lu", eError, mSensorIndex);
109 eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
110 OMX_CommandPortDisable,
111 OMX_ALL,
112 NULL);
113
114 if(eError != OMX_ErrorNone) {
115 CAMHAL_LOGEB("OMX_SendCommand(OMX_CommandPortDisable) -0x%x", eError);
116 }
117 GOTO_EXIT_IF((eError != OMX_ErrorNone), eError);
118
119 // Register for port enable event
120 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
121 OMX_EventCmdComplete,
122 OMX_CommandPortEnable,
123 mCameraAdapterParameters.mPrevPortIndex,
124 mInitSem);
125 if(ret != NO_ERROR) {
126 CAMHAL_LOGEB("Error in registering for event %d", ret);
127 goto EXIT;
128 }
129
130 // Enable PREVIEW Port
131 eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
132 OMX_CommandPortEnable,
133 mCameraAdapterParameters.mPrevPortIndex,
134 NULL);
135 if(eError != OMX_ErrorNone) {
136 CAMHAL_LOGEB("OMX_SendCommand(OMX_CommandPortEnable) -0x%x", eError);
137 }
138 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
139
140 // Wait for the port enable event to occur
141 ret = mInitSem.WaitTimeout(OMX_CMD_TIMEOUT);
142 if ( NO_ERROR == ret ) {
143 CAMHAL_LOGDA("-Port enable event arrived");
144 } else {
145 ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
146 OMX_EventCmdComplete,
147 OMX_CommandPortEnable,
148 mCameraAdapterParameters.mPrevPortIndex,
149 NULL);
150 CAMHAL_LOGEA("Timeout for enabling preview port expired!");
151 goto EXIT;
152 }
153
154 // Select the sensor
155 OMX_CONFIG_SENSORSELECTTYPE sensorSelect;
156 OMX_INIT_STRUCT_PTR (&sensorSelect, OMX_CONFIG_SENSORSELECTTYPE);
157 sensorSelect.eSensor = (OMX_SENSORSELECT) mSensorIndex;
158 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, ( OMX_INDEXTYPE ) OMX_TI_IndexConfigSensorSelect, &sensorSelect);
159 if ( OMX_ErrorNone != eError ) {
160 CAMHAL_LOGEB("Error while selecting the sensor index as %d - 0x%x", mSensorIndex, eError);
161 return BAD_VALUE;
162 } else {
163 CAMHAL_LOGDB("Sensor %d selected successfully", mSensorIndex);
164 }
165
166 printComponentVersion(mCameraAdapterParameters.mHandleComp);
167
168 mBracketingEnabled = false;
169 mBracketingBuffersQueuedCount = 0;
170 mBracketingRange = 1;
171 mLastBracetingBufferIdx = 0;
172 mOMXStateSwitch = false;
173
174 mCaptureSignalled = false;
175 mCaptureConfigured = false;
176 mRecording = false;
177 mWaitingForSnapshot = false;
178 mSnapshotCount = 0;
179 mComponentState = OMX_StateLoaded;
180
181 mCapMode = HIGH_QUALITY;
182 mIPP = IPP_NULL;
183 mVstabEnabled = false;
184 mVnfEnabled = false;
185 mBurstFrames = 1;
186 mCapturedFrames = 0;
187 mPictureQuality = 100;
188 mCurrentZoomIdx = 0;
189 mTargetZoomIdx = 0;
190 mPreviousZoomIndx = 0;
191 mReturnZoomStatus = false;
192 mZoomInc = 1;
193 mZoomParameterIdx = 0;
194 mExposureBracketingValidEntries = 0;
195 mSensorOverclock = false;
196
197 mDeviceOrientation = 0;
198 mCapabilities = caps;
199 mZoomUpdating = false;
200 mZoomUpdate = false;
201
202 mEXIFData.mGPSData.mAltitudeValid = false;
203 mEXIFData.mGPSData.mDatestampValid = false;
204 mEXIFData.mGPSData.mLatValid = false;
205 mEXIFData.mGPSData.mLongValid = false;
206 mEXIFData.mGPSData.mMapDatumValid = false;
207 mEXIFData.mGPSData.mProcMethodValid = false;
208 mEXIFData.mGPSData.mVersionIdValid = false;
209 mEXIFData.mGPSData.mTimeStampValid = false;
210 mEXIFData.mModelValid = false;
211 mEXIFData.mMakeValid = false;
212
213 // initialize command handling thread
214 if(mCommandHandler.get() == NULL)
215 mCommandHandler = new CommandHandler(this);
216
217 if ( NULL == mCommandHandler.get() )
218 {
219 CAMHAL_LOGEA("Couldn't create command handler");
220 return NO_MEMORY;
221 }
222
223 ret = mCommandHandler->run("CallbackThread", PRIORITY_URGENT_DISPLAY);
224 if ( ret != NO_ERROR )
225 {
226 if( ret == INVALID_OPERATION){
227 CAMHAL_LOGDA("command handler thread already runnning!!");
228 ret = NO_ERROR;
229 } else
230 {
231 CAMHAL_LOGEA("Couldn't run command handlerthread");
232 return ret;
233 }
234 }
235
236 // initialize omx callback handling thread
237 if(mOMXCallbackHandler.get() == NULL)
238 mOMXCallbackHandler = new OMXCallbackHandler(this);
239
240 if ( NULL == mOMXCallbackHandler.get() )
241 {
242 CAMHAL_LOGEA("Couldn't create omx callback handler");
243 return NO_MEMORY;
244 }
245
246 ret = mOMXCallbackHandler->run("OMXCallbackThread", PRIORITY_URGENT_DISPLAY);
247 if ( ret != NO_ERROR )
248 {
249 if( ret == INVALID_OPERATION){
250 CAMHAL_LOGDA("omx callback handler thread already runnning!!");
251 ret = NO_ERROR;
252 }else
253 {
254 CAMHAL_LOGEA("Couldn't run omx callback handler thread");
255 return ret;
256 }
257 }
258
259 //Remove any unhandled events
260 if (!mEventSignalQ.isEmpty()) {
261 for (unsigned int i = 0 ;i < mEventSignalQ.size(); i++ ) {
262 TIUTILS::Message *msg = mEventSignalQ.itemAt(i);
263 //remove from queue and free msg
264 mEventSignalQ.removeAt(i);
265 if ( NULL != msg ) {
266 free(msg);
267 }
268 }
269 }
270
271 OMX_INIT_STRUCT_PTR (&mRegionPriority, OMX_TI_CONFIG_3A_REGION_PRIORITY);
272 OMX_INIT_STRUCT_PTR (&mFacePriority, OMX_TI_CONFIG_3A_FACE_PRIORITY);
273 mRegionPriority.nPortIndex = OMX_ALL;
274 mFacePriority.nPortIndex = OMX_ALL;
275
276 //Setting this flag will that the first setParameter call will apply all 3A settings
277 //and will not conditionally apply based on current values.
278 mFirstTimeInit = true;
279
280 memset(mExposureBracketingValues, 0, EXP_BRACKET_RANGE*sizeof(int));
281 mMeasurementEnabled = false;
282 mFaceDetectionRunning = false;
283 mFaceDetectionPaused = false;
284
285 memset(&mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex], 0, sizeof(OMXCameraPortParameters));
286 memset(&mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex], 0, sizeof(OMXCameraPortParameters));
287
288 //Initialize 3A defaults
289 ret = apply3ADefaults(mParameters3A);
290 if ( NO_ERROR != ret ) {
291 CAMHAL_LOGEA("Couldn't apply 3A defaults!");
292 goto EXIT;
293 }
294
295 LOG_FUNCTION_NAME_EXIT;
296 return ErrorUtils::omxToAndroidError(eError);
297
298 EXIT:
299
300 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
301 performCleanupAfterError();
302 LOG_FUNCTION_NAME_EXIT;
303 return ErrorUtils::omxToAndroidError(eError);
304 }
305
performCleanupAfterError()306 void OMXCameraAdapter::performCleanupAfterError()
307 {
308 if(mCameraAdapterParameters.mHandleComp)
309 {
310 ///Free the OMX component handle in case of error
311 OMX_FreeHandle(mCameraAdapterParameters.mHandleComp);
312 mCameraAdapterParameters.mHandleComp = NULL;
313 }
314
315 ///De-init the OMX
316 OMX_Deinit();
317 mComponentState = OMX_StateInvalid;
318 }
319
getPortParams(CameraFrame::FrameType frameType)320 OMXCameraAdapter::OMXCameraPortParameters *OMXCameraAdapter::getPortParams(CameraFrame::FrameType frameType)
321 {
322 OMXCameraAdapter::OMXCameraPortParameters *ret = NULL;
323
324 switch ( frameType )
325 {
326 case CameraFrame::IMAGE_FRAME:
327 case CameraFrame::RAW_FRAME:
328 ret = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
329 break;
330 case CameraFrame::PREVIEW_FRAME_SYNC:
331 case CameraFrame::SNAPSHOT_FRAME:
332 case CameraFrame::VIDEO_FRAME_SYNC:
333 ret = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex];
334 break;
335 case CameraFrame::FRAME_DATA_SYNC:
336 ret = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mMeasurementPortIndex];
337 break;
338 default:
339 break;
340 };
341
342 return ret;
343 }
344
fillThisBuffer(void * frameBuf,CameraFrame::FrameType frameType)345 status_t OMXCameraAdapter::fillThisBuffer(void* frameBuf, CameraFrame::FrameType frameType)
346 {
347 status_t ret = NO_ERROR;
348 OMXCameraPortParameters *port = NULL;
349 OMX_ERRORTYPE eError = OMX_ErrorNone;
350 BaseCameraAdapter::AdapterState state;
351 BaseCameraAdapter::getState(state);
352
353 if ( ( PREVIEW_ACTIVE & state ) != PREVIEW_ACTIVE )
354 {
355 return NO_INIT;
356 }
357
358 if ( NULL == frameBuf )
359 {
360 return -EINVAL;
361 }
362
363 if ( (NO_ERROR == ret) &&
364 ((CameraFrame::IMAGE_FRAME == frameType) || (CameraFrame::RAW_FRAME == frameType)) &&
365 (1 > mCapturedFrames) &&
366 (!mBracketingEnabled)) {
367 // Signal end of image capture
368 if ( NULL != mEndImageCaptureCallback) {
369 mEndImageCaptureCallback(mEndCaptureData);
370 }
371 return NO_ERROR;
372 }
373
374 if ( NO_ERROR == ret )
375 {
376 port = getPortParams(frameType);
377 if ( NULL == port )
378 {
379 CAMHAL_LOGEB("Invalid frameType 0x%x", frameType);
380 ret = -EINVAL;
381 }
382 }
383
384 if ( NO_ERROR == ret )
385 {
386
387 for ( int i = 0 ; i < port->mNumBufs ; i++)
388 {
389 if ( port->mBufferHeader[i]->pBuffer == frameBuf )
390 {
391 eError = OMX_FillThisBuffer(mCameraAdapterParameters.mHandleComp, port->mBufferHeader[i]);
392 if ( eError != OMX_ErrorNone )
393 {
394 CAMHAL_LOGEB("OMX_FillThisBuffer 0x%x", eError);
395 goto EXIT;
396 }
397 mFramesWithDucati++;
398 break;
399 }
400 }
401
402 }
403
404 LOG_FUNCTION_NAME_EXIT;
405 return ret;
406
407 EXIT:
408 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
409 performCleanupAfterError();
410 //Since fillthisbuffer is called asynchronously, make sure to signal error to the app
411 mErrorNotifier->errorNotify(CAMERA_ERROR_HARD);
412 LOG_FUNCTION_NAME_EXIT;
413 return (ret | ErrorUtils::omxToAndroidError(eError));
414 }
415
setParameters(const CameraParameters & params)416 status_t OMXCameraAdapter::setParameters(const CameraParameters ¶ms)
417 {
418 LOG_FUNCTION_NAME;
419
420 const char * str = NULL;
421 int mode = 0;
422 status_t ret = NO_ERROR;
423 bool updateImagePortParams = false;
424 int minFramerate, maxFramerate, frameRate;
425 const char *valstr = NULL;
426 const char *oldstr = NULL;
427 int w, h;
428 OMX_COLOR_FORMATTYPE pixFormat;
429 BaseCameraAdapter::AdapterState state;
430 BaseCameraAdapter::getState(state);
431
432 ///@todo Include more camera parameters
433 if ( (valstr = params.getPreviewFormat()) != NULL )
434 {
435 if (strcmp(valstr, (const char *) CameraParameters::PIXEL_FORMAT_YUV422I) == 0)
436 {
437 CAMHAL_LOGDA("CbYCrY format selected");
438 pixFormat = OMX_COLOR_FormatCbYCrY;
439 }
440 else if(strcmp(valstr, (const char *) CameraParameters::PIXEL_FORMAT_YUV420SP) == 0 ||
441 strcmp(valstr, (const char *) CameraParameters::PIXEL_FORMAT_YUV420P) == 0)
442 {
443 CAMHAL_LOGDA("YUV420SP format selected");
444 pixFormat = OMX_COLOR_FormatYUV420SemiPlanar;
445 }
446 else if(strcmp(valstr, (const char *) CameraParameters::PIXEL_FORMAT_RGB565) == 0)
447 {
448 CAMHAL_LOGDA("RGB565 format selected");
449 pixFormat = OMX_COLOR_Format16bitRGB565;
450 }
451 else
452 {
453 CAMHAL_LOGDA("Invalid format, CbYCrY format selected as default");
454 pixFormat = OMX_COLOR_FormatCbYCrY;
455 }
456 }
457 else
458 {
459 CAMHAL_LOGEA("Preview format is NULL, defaulting to CbYCrY");
460 pixFormat = OMX_COLOR_FormatCbYCrY;
461 }
462
463 OMXCameraPortParameters *cap;
464 cap = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex];
465
466 params.getPreviewSize(&w, &h);
467 frameRate = params.getPreviewFrameRate();
468 minFramerate = params.getInt(TICameraParameters::KEY_MINFRAMERATE);
469 maxFramerate = params.getInt(TICameraParameters::KEY_MAXFRAMERATE);
470 if ( ( 0 < minFramerate ) &&
471 ( 0 < maxFramerate ) )
472 {
473 if ( minFramerate > maxFramerate )
474 {
475 CAMHAL_LOGEA(" Min FPS set higher than MAX. So setting MIN and MAX to the higher value");
476 maxFramerate = minFramerate;
477 }
478
479 if ( 0 >= frameRate )
480 {
481 frameRate = maxFramerate;
482 }
483
484 if( ( cap->mMinFrameRate != minFramerate ) ||
485 ( cap->mMaxFrameRate != maxFramerate ) )
486 {
487 cap->mMinFrameRate = minFramerate;
488 cap->mMaxFrameRate = maxFramerate;
489 setVFramerate(cap->mMinFrameRate, cap->mMaxFrameRate);
490 }
491 }
492
493 // TODO(XXX): Limiting 1080p to (24,24) or (15,15) for now. Need to remove later.
494 if ((w >= 1920) && (h >= 1080)) {
495 cap->mMaxFrameRate = cap->mMinFrameRate;
496 setVFramerate(cap->mMinFrameRate, cap->mMaxFrameRate);
497 }
498
499 if ( 0 < frameRate )
500 {
501 cap->mColorFormat = pixFormat;
502 cap->mWidth = w;
503 cap->mHeight = h;
504 cap->mFrameRate = frameRate;
505
506 CAMHAL_LOGVB("Prev: cap.mColorFormat = %d", (int)cap->mColorFormat);
507 CAMHAL_LOGVB("Prev: cap.mWidth = %d", (int)cap->mWidth);
508 CAMHAL_LOGVB("Prev: cap.mHeight = %d", (int)cap->mHeight);
509 CAMHAL_LOGVB("Prev: cap.mFrameRate = %d", (int)cap->mFrameRate);
510
511 //TODO: Add an additional parameter for video resolution
512 //use preview resolution for now
513 cap = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex];
514 cap->mColorFormat = pixFormat;
515 cap->mWidth = w;
516 cap->mHeight = h;
517 cap->mFrameRate = frameRate;
518
519 CAMHAL_LOGVB("Video: cap.mColorFormat = %d", (int)cap->mColorFormat);
520 CAMHAL_LOGVB("Video: cap.mWidth = %d", (int)cap->mWidth);
521 CAMHAL_LOGVB("Video: cap.mHeight = %d", (int)cap->mHeight);
522 CAMHAL_LOGVB("Video: cap.mFrameRate = %d", (int)cap->mFrameRate);
523
524 ///mStride is set from setBufs() while passing the APIs
525 cap->mStride = 4096;
526 cap->mBufSize = cap->mStride * cap->mHeight;
527 }
528
529 if ( ( cap->mWidth >= 1920 ) &&
530 ( cap->mHeight >= 1080 ) &&
531 ( cap->mFrameRate >= FRAME_RATE_FULL_HD ) &&
532 ( !mSensorOverclock ) )
533 {
534 mOMXStateSwitch = true;
535 }
536 else if ( ( ( cap->mWidth < 1920 ) ||
537 ( cap->mHeight < 1080 ) ||
538 ( cap->mFrameRate < FRAME_RATE_FULL_HD ) ) &&
539 ( mSensorOverclock ) )
540 {
541 mOMXStateSwitch = true;
542 }
543
544 if ( (valstr = params.get(TICameraParameters::KEY_MEASUREMENT_ENABLE)) != NULL )
545 {
546 if (strcmp(valstr, (const char *) TICameraParameters::MEASUREMENT_ENABLE) == 0)
547 {
548 mMeasurementEnabled = true;
549 }
550 else if (strcmp(valstr, (const char *) TICameraParameters::MEASUREMENT_DISABLE) == 0)
551 {
552 mMeasurementEnabled = false;
553 }
554 else
555 {
556 mMeasurementEnabled = false;
557 }
558 }
559 else
560 {
561 //Disable measurement data by default
562 mMeasurementEnabled = false;
563 }
564
565 ret |= setParametersCapture(params, state);
566
567 ret |= setParameters3A(params, state);
568
569 ret |= setParametersAlgo(params, state);
570
571 ret |= setParametersFocus(params, state);
572
573 ret |= setParametersFD(params, state);
574
575 ret |= setParametersZoom(params, state);
576
577 ret |= setParametersEXIF(params, state);
578
579 mParams = params;
580 mFirstTimeInit = false;
581
582 LOG_FUNCTION_NAME_EXIT;
583 return ret;
584 }
585
saveFile(unsigned char * buff,int width,int height,int format)586 void saveFile(unsigned char *buff, int width, int height, int format) {
587 static int counter = 1;
588 int fd = -1;
589 char fn[256];
590
591 LOG_FUNCTION_NAME;
592
593 fn[0] = 0;
594 sprintf(fn, "/preview%03d.yuv", counter);
595 fd = open(fn, O_CREAT | O_WRONLY | O_SYNC | O_TRUNC, 0777);
596 if(fd < 0) {
597 LOGE("Unable to open file %s: %s", fn, strerror(fd));
598 return;
599 }
600
601 CAMHAL_LOGVB("Copying from 0x%x, size=%d x %d", buff, width, height);
602
603 //method currently supports only nv12 dumping
604 int stride = width;
605 uint8_t *bf = (uint8_t*) buff;
606 for(int i=0;i<height;i++)
607 {
608 write(fd, bf, width);
609 bf += 4096;
610 }
611
612 for(int i=0;i<height/2;i++)
613 {
614 write(fd, bf, stride);
615 bf += 4096;
616 }
617
618 close(fd);
619
620
621 counter++;
622
623 LOG_FUNCTION_NAME_EXIT;
624 }
625
getParameters(CameraParameters & params)626 void OMXCameraAdapter::getParameters(CameraParameters& params)
627 {
628 status_t ret = NO_ERROR;
629 OMX_CONFIG_EXPOSUREVALUETYPE exp;
630 OMX_ERRORTYPE eError = OMX_ErrorNone;
631 BaseCameraAdapter::AdapterState state;
632 BaseCameraAdapter::getState(state);
633 const char *valstr = NULL;
634 LOG_FUNCTION_NAME;
635
636 if( mParameters3A.SceneMode != OMX_Manual ) {
637 const char *valstr_supported = NULL;
638
639 // if preview is not started...we still need to feedback the proper params
640 // look up the settings in the LUT
641 if (((state & PREVIEW_ACTIVE) == 0) && mCapabilities) {
642 const SceneModesEntry* entry = NULL;
643 entry = getSceneModeEntry(mCapabilities->get(CameraProperties::CAMERA_NAME),
644 (OMX_SCENEMODETYPE) mParameters3A.SceneMode);
645 if(entry) {
646 mParameters3A.Focus = entry->focus;
647 mParameters3A.FlashMode = entry->flash;
648 mParameters3A.WhiteBallance = entry->wb;
649 }
650 }
651
652 valstr = getLUTvalue_OMXtoHAL(mParameters3A.WhiteBallance, WBalLUT);
653 valstr_supported = mParams.get(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE);
654 if (valstr && valstr_supported && strstr(valstr_supported, valstr))
655 params.set(CameraParameters::KEY_WHITE_BALANCE , valstr);
656
657 valstr = getLUTvalue_OMXtoHAL(mParameters3A.FlashMode, FlashLUT);
658 valstr_supported = mParams.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES);
659 if (valstr && valstr_supported && strstr(valstr_supported, valstr))
660 params.set(CameraParameters::KEY_FLASH_MODE, valstr);
661
662 if ((mParameters3A.Focus == OMX_IMAGE_FocusControlAuto) &&
663 (mCapMode != OMXCameraAdapter::VIDEO_MODE)) {
664 valstr = CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
665 } else {
666 valstr = getLUTvalue_OMXtoHAL(mParameters3A.Focus, FocusLUT);
667 }
668 valstr_supported = mParams.get(CameraParameters::KEY_SUPPORTED_FOCUS_MODES);
669 if (valstr && valstr_supported && strstr(valstr_supported, valstr))
670 params.set(CameraParameters::KEY_FOCUS_MODE, valstr);
671 }
672
673 //Query focus distances only when focus is running
674 if ( ( AF_ACTIVE & state ) ||
675 ( NULL == mParameters.get(CameraParameters::KEY_FOCUS_DISTANCES) ) )
676 {
677 updateFocusDistances(params);
678 }
679 else
680 {
681 params.set(CameraParameters::KEY_FOCUS_DISTANCES,
682 mParameters.get(CameraParameters::KEY_FOCUS_DISTANCES));
683 }
684
685 OMX_INIT_STRUCT_PTR (&exp, OMX_CONFIG_EXPOSUREVALUETYPE);
686 exp.nPortIndex = OMX_ALL;
687
688 eError = OMX_GetConfig(mCameraAdapterParameters.mHandleComp,
689 OMX_IndexConfigCommonExposureValue,
690 &exp);
691 if ( OMX_ErrorNone == eError )
692 {
693 params.set(TICameraParameters::KEY_CURRENT_ISO, exp.nSensitivity);
694 }
695 else
696 {
697 CAMHAL_LOGEB("OMX error 0x%x, while retrieving current ISO value", eError);
698 }
699
700 {
701 Mutex::Autolock lock(mZoomLock);
702 //Immediate zoom should not be avaialable while smooth zoom is running
703 if ( ZOOM_ACTIVE & state )
704 {
705 if ( mZoomParameterIdx != mCurrentZoomIdx )
706 {
707 mZoomParameterIdx += mZoomInc;
708 }
709 params.set( CameraParameters::KEY_ZOOM, mZoomParameterIdx);
710 if ( ( mCurrentZoomIdx == mTargetZoomIdx ) &&
711 ( mZoomParameterIdx == mCurrentZoomIdx ) )
712 {
713
714 if ( NO_ERROR == ret )
715 {
716
717 ret = BaseCameraAdapter::setState(CAMERA_STOP_SMOOTH_ZOOM);
718
719 if ( NO_ERROR == ret )
720 {
721 ret = BaseCameraAdapter::commitState();
722 }
723 else
724 {
725 ret |= BaseCameraAdapter::rollbackState();
726 }
727
728 }
729
730 }
731
732 CAMHAL_LOGDB("CameraParameters Zoom = %d", mCurrentZoomIdx);
733 }
734 else
735 {
736 params.set( CameraParameters::KEY_ZOOM, mCurrentZoomIdx);
737 }
738 }
739
740 //Populate current lock status
741 if( (valstr = mParams.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK)) != NULL )
742 {
743 CAMHAL_LOGDB("Auto Exposure Lock get %s", mParams.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK));
744 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK, valstr);
745 }
746
747 if( (valstr = mParams.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK)) != NULL )
748 {
749 CAMHAL_LOGDB("Auto WhiteBalance Lock get %s", mParams.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK));
750 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK, valstr);
751 }
752
753
754 LOG_FUNCTION_NAME_EXIT;
755 }
756
setFormat(OMX_U32 port,OMXCameraPortParameters & portParams)757 status_t OMXCameraAdapter::setFormat(OMX_U32 port, OMXCameraPortParameters &portParams)
758 {
759 size_t bufferCount;
760
761 LOG_FUNCTION_NAME;
762
763 OMX_ERRORTYPE eError = OMX_ErrorNone;
764 OMX_PARAM_PORTDEFINITIONTYPE portCheck;
765
766 OMX_INIT_STRUCT_PTR (&portCheck, OMX_PARAM_PORTDEFINITIONTYPE);
767
768 portCheck.nPortIndex = port;
769
770 eError = OMX_GetParameter (mCameraAdapterParameters.mHandleComp,
771 OMX_IndexParamPortDefinition, &portCheck);
772 if(eError!=OMX_ErrorNone)
773 {
774 CAMHAL_LOGEB("OMX_GetParameter - %x", eError);
775 }
776 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
777
778 if ( OMX_CAMERA_PORT_VIDEO_OUT_PREVIEW == port )
779 {
780 portCheck.format.video.nFrameWidth = portParams.mWidth;
781 portCheck.format.video.nFrameHeight = portParams.mHeight;
782 portCheck.format.video.eColorFormat = portParams.mColorFormat;
783 portCheck.format.video.nStride = portParams.mStride;
784 if( ( portCheck.format.video.nFrameWidth >= 1920 ) &&
785 ( portCheck.format.video.nFrameHeight >= 1080 ) &&
786 ( portParams.mFrameRate >= FRAME_RATE_FULL_HD ) )
787 {
788 setSensorOverclock(true);
789 }
790 else
791 {
792 setSensorOverclock(false);
793 }
794
795 portCheck.format.video.xFramerate = portParams.mFrameRate<<16;
796 portCheck.nBufferSize = portParams.mStride * portParams.mHeight;
797 portCheck.nBufferCountActual = portParams.mNumBufs;
798 mFocusThreshold = FOCUS_THRESHOLD * portParams.mFrameRate;
799 }
800 else if ( OMX_CAMERA_PORT_IMAGE_OUT_IMAGE == port )
801 {
802 portCheck.format.image.nFrameWidth = portParams.mWidth;
803 portCheck.format.image.nFrameHeight = portParams.mHeight;
804 if ( OMX_COLOR_FormatUnused == portParams.mColorFormat && mCodingMode == CodingNone )
805 {
806 portCheck.format.image.eColorFormat = OMX_COLOR_FormatCbYCrY;
807 portCheck.format.image.eCompressionFormat = OMX_IMAGE_CodingJPEG;
808 }
809 else if ( OMX_COLOR_FormatUnused == portParams.mColorFormat && mCodingMode == CodingJPS )
810 {
811 portCheck.format.image.eColorFormat = OMX_COLOR_FormatCbYCrY;
812 portCheck.format.image.eCompressionFormat = (OMX_IMAGE_CODINGTYPE) OMX_TI_IMAGE_CodingJPS;
813 }
814 else if ( OMX_COLOR_FormatUnused == portParams.mColorFormat && mCodingMode == CodingMPO )
815 {
816 portCheck.format.image.eColorFormat = OMX_COLOR_FormatCbYCrY;
817 portCheck.format.image.eCompressionFormat = (OMX_IMAGE_CODINGTYPE) OMX_TI_IMAGE_CodingMPO;
818 }
819 else if ( OMX_COLOR_FormatUnused == portParams.mColorFormat && mCodingMode == CodingRAWJPEG )
820 {
821 //TODO: OMX_IMAGE_CodingJPEG should be changed to OMX_IMAGE_CodingRAWJPEG when
822 // RAW format is supported
823 portCheck.format.image.eColorFormat = OMX_COLOR_FormatCbYCrY;
824 portCheck.format.image.eCompressionFormat = OMX_IMAGE_CodingJPEG;
825 }
826 else if ( OMX_COLOR_FormatUnused == portParams.mColorFormat && mCodingMode == CodingRAWMPO )
827 {
828 //TODO: OMX_IMAGE_CodingJPEG should be changed to OMX_IMAGE_CodingRAWMPO when
829 // RAW format is supported
830 portCheck.format.image.eColorFormat = OMX_COLOR_FormatCbYCrY;
831 portCheck.format.image.eCompressionFormat = OMX_IMAGE_CodingJPEG;
832 }
833 else
834 {
835 portCheck.format.image.eColorFormat = portParams.mColorFormat;
836 portCheck.format.image.eCompressionFormat = OMX_IMAGE_CodingUnused;
837 }
838
839 //Stride for 1D tiler buffer is zero
840 portCheck.format.image.nStride = 0;
841 portCheck.nBufferSize = portParams.mStride * portParams.mWidth * portParams.mHeight;
842 portCheck.nBufferCountActual = portParams.mNumBufs;
843 }
844 else
845 {
846 CAMHAL_LOGEB("Unsupported port index 0x%x", (unsigned int)port);
847 }
848
849 eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp,
850 OMX_IndexParamPortDefinition, &portCheck);
851 if(eError!=OMX_ErrorNone)
852 {
853 CAMHAL_LOGEB("OMX_SetParameter - %x", eError);
854 }
855 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
856
857 /* check if parameters are set correctly by calling GetParameter() */
858 eError = OMX_GetParameter(mCameraAdapterParameters.mHandleComp,
859 OMX_IndexParamPortDefinition, &portCheck);
860 if(eError!=OMX_ErrorNone)
861 {
862 CAMHAL_LOGEB("OMX_GetParameter - %x", eError);
863 }
864 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
865
866 portParams.mBufSize = portCheck.nBufferSize;
867
868 if ( OMX_CAMERA_PORT_IMAGE_OUT_IMAGE == port )
869 {
870 CAMHAL_LOGDB("\n *** IMG Width = %ld", portCheck.format.image.nFrameWidth);
871 CAMHAL_LOGDB("\n ***IMG Height = %ld", portCheck.format.image.nFrameHeight);
872
873 CAMHAL_LOGDB("\n ***IMG IMG FMT = %x", portCheck.format.image.eColorFormat);
874 CAMHAL_LOGDB("\n ***IMG portCheck.nBufferSize = %ld\n",portCheck.nBufferSize);
875 CAMHAL_LOGDB("\n ***IMG portCheck.nBufferCountMin = %ld\n",
876 portCheck.nBufferCountMin);
877 CAMHAL_LOGDB("\n ***IMG portCheck.nBufferCountActual = %ld\n",
878 portCheck.nBufferCountActual);
879 CAMHAL_LOGDB("\n ***IMG portCheck.format.image.nStride = %ld\n",
880 portCheck.format.image.nStride);
881 }
882 else
883 {
884 CAMHAL_LOGDB("\n *** PRV Width = %ld", portCheck.format.video.nFrameWidth);
885 CAMHAL_LOGDB("\n ***PRV Height = %ld", portCheck.format.video.nFrameHeight);
886
887 CAMHAL_LOGDB("\n ***PRV IMG FMT = %x", portCheck.format.video.eColorFormat);
888 CAMHAL_LOGDB("\n ***PRV portCheck.nBufferSize = %ld\n",portCheck.nBufferSize);
889 CAMHAL_LOGDB("\n ***PRV portCheck.nBufferCountMin = %ld\n",
890 portCheck.nBufferCountMin);
891 CAMHAL_LOGDB("\n ***PRV portCheck.nBufferCountActual = %ld\n",
892 portCheck.nBufferCountActual);
893 CAMHAL_LOGDB("\n ***PRV portCheck.format.video.nStride = %ld\n",
894 portCheck.format.video.nStride);
895 }
896
897 LOG_FUNCTION_NAME_EXIT;
898
899 return ErrorUtils::omxToAndroidError(eError);
900
901 EXIT:
902
903 CAMHAL_LOGEB("Exiting function %s because of eError=%x", __FUNCTION__, eError);
904
905 LOG_FUNCTION_NAME_EXIT;
906
907 return ErrorUtils::omxToAndroidError(eError);
908 }
909
flushBuffers()910 status_t OMXCameraAdapter::flushBuffers()
911 {
912 status_t ret = NO_ERROR;
913 OMX_ERRORTYPE eError = OMX_ErrorNone;
914 TIMM_OSAL_ERRORTYPE err;
915 TIMM_OSAL_U32 uRequestedEvents = OMXCameraAdapter::CAMERA_PORT_FLUSH;
916 TIMM_OSAL_U32 pRetrievedEvents;
917
918 if ( 0 != mFlushSem.Count() )
919 {
920 CAMHAL_LOGEB("Error mFlushSem semaphore count %d", mFlushSem.Count());
921 LOG_FUNCTION_NAME_EXIT;
922 return NO_INIT;
923 }
924
925 LOG_FUNCTION_NAME;
926
927 OMXCameraPortParameters * mPreviewData = NULL;
928 mPreviewData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex];
929
930 ///Register for the FLUSH event
931 ///This method just inserts a message in Event Q, which is checked in the callback
932 ///The sempahore passed is signalled by the callback
933 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
934 OMX_EventCmdComplete,
935 OMX_CommandFlush,
936 OMX_CAMERA_PORT_VIDEO_OUT_PREVIEW,
937 mFlushSem);
938 if(ret!=NO_ERROR)
939 {
940 CAMHAL_LOGEB("Error in registering for event %d", ret);
941 goto EXIT;
942 }
943
944 ///Send FLUSH command to preview port
945 eError = OMX_SendCommand (mCameraAdapterParameters.mHandleComp,
946 OMX_CommandFlush,
947 mCameraAdapterParameters.mPrevPortIndex,
948 NULL);
949
950 if(eError!=OMX_ErrorNone)
951 {
952 CAMHAL_LOGEB("OMX_SendCommand(OMX_CommandFlush)-0x%x", eError);
953 }
954 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
955
956 CAMHAL_LOGDA("Waiting for flush event");
957
958 ///Wait for the FLUSH event to occur
959 ret = mFlushSem.WaitTimeout(OMX_CMD_TIMEOUT);
960
961 //If somethiing bad happened while we wait
962 if (mComponentState == OMX_StateInvalid)
963 {
964 CAMHAL_LOGEA("Invalid State after Flush Exitting!!!");
965 goto EXIT;
966 }
967
968 if ( NO_ERROR == ret )
969 {
970 CAMHAL_LOGDA("Flush event received");
971 }
972 else
973 {
974 ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
975 OMX_EventCmdComplete,
976 OMX_CommandFlush,
977 OMX_CAMERA_PORT_VIDEO_OUT_PREVIEW,
978 NULL);
979 CAMHAL_LOGDA("Flush event timeout expired");
980 goto EXIT;
981 }
982
983 LOG_FUNCTION_NAME_EXIT;
984
985 return (ret | ErrorUtils::omxToAndroidError(eError));
986
987 EXIT:
988 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
989 performCleanupAfterError();
990 LOG_FUNCTION_NAME_EXIT;
991 return (ret | ErrorUtils::omxToAndroidError(eError));
992 }
993
994 ///API to give the buffers to Adapter
useBuffers(CameraMode mode,void * bufArr,int num,size_t length,unsigned int queueable)995 status_t OMXCameraAdapter::useBuffers(CameraMode mode, void* bufArr, int num, size_t length, unsigned int queueable)
996 {
997 OMX_ERRORTYPE eError = OMX_ErrorNone;
998 status_t ret = NO_ERROR;
999
1000 LOG_FUNCTION_NAME;
1001
1002 switch(mode)
1003 {
1004 case CAMERA_PREVIEW:
1005 mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex].mNumBufs = num;
1006 mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex].mMaxQueueable = queueable;
1007 ret = UseBuffersPreview(bufArr, num);
1008 break;
1009
1010 case CAMERA_IMAGE_CAPTURE:
1011 mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex].mNumBufs = num;
1012 mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex].mMaxQueueable = queueable;
1013 ret = UseBuffersCapture(bufArr, num);
1014 break;
1015
1016 case CAMERA_VIDEO:
1017 mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex].mNumBufs = num;
1018 mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex].mMaxQueueable = queueable;
1019 ret = UseBuffersPreview(bufArr, num);
1020 break;
1021
1022 case CAMERA_MEASUREMENT:
1023 mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mMeasurementPortIndex].mNumBufs = num;
1024 mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mMeasurementPortIndex].mMaxQueueable = queueable;
1025 ret = UseBuffersPreviewData(bufArr, num);
1026 break;
1027
1028 }
1029
1030 LOG_FUNCTION_NAME_EXIT;
1031
1032 return ret;
1033 }
1034
UseBuffersPreviewData(void * bufArr,int num)1035 status_t OMXCameraAdapter::UseBuffersPreviewData(void* bufArr, int num)
1036 {
1037 status_t ret = NO_ERROR;
1038 OMX_ERRORTYPE eError = OMX_ErrorNone;
1039 OMXCameraPortParameters * measurementData = NULL;
1040 uint32_t *buffers;
1041 Mutex::Autolock lock( mPreviewDataBufferLock);
1042
1043 LOG_FUNCTION_NAME;
1044
1045 if ( mComponentState != OMX_StateLoaded )
1046 {
1047 CAMHAL_LOGEA("Calling UseBuffersPreviewData() when not in LOADED state");
1048 return BAD_VALUE;
1049 }
1050
1051 if ( NULL == bufArr )
1052 {
1053 CAMHAL_LOGEA("NULL pointer passed for buffArr");
1054 return BAD_VALUE;
1055 }
1056
1057 if ( 0 != mUsePreviewDataSem.Count() )
1058 {
1059 CAMHAL_LOGEB("Error mUsePreviewDataSem semaphore count %d", mUsePreviewDataSem.Count());
1060 LOG_FUNCTION_NAME_EXIT;
1061 return NO_INIT;
1062 }
1063
1064 if ( NO_ERROR == ret )
1065 {
1066 measurementData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mMeasurementPortIndex];
1067 measurementData->mNumBufs = num ;
1068 buffers= (uint32_t*) bufArr;
1069 }
1070
1071 if ( NO_ERROR == ret )
1072 {
1073 ///Register for port enable event on measurement port
1074 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
1075 OMX_EventCmdComplete,
1076 OMX_CommandPortEnable,
1077 mCameraAdapterParameters.mMeasurementPortIndex,
1078 mUsePreviewDataSem);
1079
1080 if ( ret == NO_ERROR )
1081 {
1082 CAMHAL_LOGDB("Registering for event %d", ret);
1083 }
1084 else
1085 {
1086 CAMHAL_LOGEB("Error in registering for event %d", ret);
1087 goto EXIT;
1088 }
1089 }
1090
1091 if ( NO_ERROR == ret )
1092 {
1093 ///Enable MEASUREMENT Port
1094 eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
1095 OMX_CommandPortEnable,
1096 mCameraAdapterParameters.mMeasurementPortIndex,
1097 NULL);
1098
1099 if ( eError == OMX_ErrorNone )
1100 {
1101 CAMHAL_LOGDB("OMX_SendCommand(OMX_CommandPortEnable) -0x%x", eError);
1102 }
1103 else
1104 {
1105 CAMHAL_LOGEB("OMX_SendCommand(OMX_CommandPortEnable) -0x%x", eError);
1106 goto EXIT;
1107 }
1108 }
1109
1110 if ( NO_ERROR == ret )
1111 {
1112 ret = mUsePreviewDataSem.WaitTimeout(OMX_CMD_TIMEOUT);
1113
1114 //If somethiing bad happened while we wait
1115 if (mComponentState == OMX_StateInvalid)
1116 {
1117 CAMHAL_LOGEA("Invalid State after measurement port enable Exitting!!!");
1118 goto EXIT;
1119 }
1120
1121 if ( NO_ERROR == ret )
1122 {
1123 CAMHAL_LOGDA("Port enable event arrived on measurement port");
1124 }
1125 else
1126 {
1127 ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
1128 OMX_EventCmdComplete,
1129 OMX_CommandPortEnable,
1130 mCameraAdapterParameters.mMeasurementPortIndex,
1131 NULL);
1132 CAMHAL_LOGEA("Timeout expoired during port enable on measurement port");
1133 goto EXIT;
1134 }
1135
1136 CAMHAL_LOGDA("Port enable event arrived on measurement port");
1137 }
1138
1139 LOG_FUNCTION_NAME_EXIT;
1140
1141 return ret;
1142 EXIT:
1143 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
1144 performCleanupAfterError();
1145 LOG_FUNCTION_NAME_EXIT;
1146 return (ret | ErrorUtils::omxToAndroidError(eError));
1147 }
1148
switchToExecuting()1149 status_t OMXCameraAdapter::switchToExecuting()
1150 {
1151 status_t ret = NO_ERROR;
1152 TIUTILS::Message msg;
1153
1154 LOG_FUNCTION_NAME;
1155
1156 mStateSwitchLock.lock();
1157 msg.command = CommandHandler::CAMERA_SWITCH_TO_EXECUTING;
1158 msg.arg1 = mErrorNotifier;
1159 ret = mCommandHandler->put(&msg);
1160
1161 LOG_FUNCTION_NAME;
1162
1163 return ret;
1164 }
1165
doSwitchToExecuting()1166 status_t OMXCameraAdapter::doSwitchToExecuting()
1167 {
1168 status_t ret = NO_ERROR;
1169 OMX_ERRORTYPE eError = OMX_ErrorNone;
1170 LOG_FUNCTION_NAME;
1171
1172 if ( (mComponentState == OMX_StateExecuting) || (mComponentState == OMX_StateInvalid) ){
1173 CAMHAL_LOGDA("Already in OMX_Executing state or OMX_StateInvalid state");
1174 mStateSwitchLock.unlock();
1175 return NO_ERROR;
1176 }
1177
1178 if ( 0 != mSwitchToExecSem.Count() ){
1179 CAMHAL_LOGEB("Error mSwitchToExecSem semaphore count %d", mSwitchToExecSem.Count());
1180 goto EXIT;
1181 }
1182
1183 ///Register for Preview port DISABLE event
1184 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
1185 OMX_EventCmdComplete,
1186 OMX_CommandPortDisable,
1187 mCameraAdapterParameters.mPrevPortIndex,
1188 mSwitchToExecSem);
1189 if ( NO_ERROR != ret ){
1190 CAMHAL_LOGEB("Error in registering Port Disable for event %d", ret);
1191 goto EXIT;
1192 }
1193 ///Disable Preview Port
1194 eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
1195 OMX_CommandPortDisable,
1196 mCameraAdapterParameters.mPrevPortIndex,
1197 NULL);
1198 ret = mSwitchToExecSem.WaitTimeout(OMX_CMD_TIMEOUT);
1199 if (ret != NO_ERROR){
1200 CAMHAL_LOGEB("Timeout PREVIEW PORT DISABLE %d", ret);
1201 }
1202
1203 CAMHAL_LOGVB("PREV PORT DISABLED %d", ret);
1204
1205 ///Register for IDLE state switch event
1206 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
1207 OMX_EventCmdComplete,
1208 OMX_CommandStateSet,
1209 OMX_StateIdle,
1210 mSwitchToExecSem);
1211 if(ret!=NO_ERROR)
1212 {
1213 CAMHAL_LOGEB("Error in IDLE STATE SWITCH %d", ret);
1214 goto EXIT;
1215 }
1216 eError = OMX_SendCommand (mCameraAdapterParameters.mHandleComp ,
1217 OMX_CommandStateSet,
1218 OMX_StateIdle,
1219 NULL);
1220 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1221 ret = mSwitchToExecSem.WaitTimeout(OMX_CMD_TIMEOUT);
1222 if (ret != NO_ERROR){
1223 CAMHAL_LOGEB("Timeout IDLE STATE SWITCH %d", ret);
1224 goto EXIT;
1225 }
1226 mComponentState = OMX_StateIdle;
1227 CAMHAL_LOGVB("OMX_SendCommand(OMX_StateIdle) 0x%x", eError);
1228
1229 ///Register for EXECUTING state switch event
1230 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
1231 OMX_EventCmdComplete,
1232 OMX_CommandStateSet,
1233 OMX_StateExecuting,
1234 mSwitchToExecSem);
1235 if(ret!=NO_ERROR)
1236 {
1237 CAMHAL_LOGEB("Error in EXECUTING STATE SWITCH %d", ret);
1238 goto EXIT;
1239 }
1240 eError = OMX_SendCommand (mCameraAdapterParameters.mHandleComp ,
1241 OMX_CommandStateSet,
1242 OMX_StateExecuting,
1243 NULL);
1244 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1245 ret = mSwitchToExecSem.WaitTimeout(OMX_CMD_TIMEOUT);
1246 if (ret != NO_ERROR){
1247 CAMHAL_LOGEB("Timeout EXEC STATE SWITCH %d", ret);
1248 goto EXIT;
1249 }
1250 mComponentState = OMX_StateExecuting;
1251 CAMHAL_LOGVB("OMX_SendCommand(OMX_StateExecuting) 0x%x", eError);
1252
1253 mStateSwitchLock.unlock();
1254
1255 LOG_FUNCTION_NAME_EXIT;
1256 return ret;
1257
1258 EXIT:
1259 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
1260 performCleanupAfterError();
1261 mStateSwitchLock.unlock();
1262 LOG_FUNCTION_NAME_EXIT;
1263 return (ret | ErrorUtils::omxToAndroidError(eError));
1264 }
1265
switchToLoaded()1266 status_t OMXCameraAdapter::switchToLoaded()
1267 {
1268 status_t ret = NO_ERROR;
1269 OMX_ERRORTYPE eError = OMX_ErrorNone;
1270
1271 LOG_FUNCTION_NAME;
1272
1273 Mutex::Autolock lock(mStateSwitchLock);
1274
1275 if ( mComponentState == OMX_StateLoaded || mComponentState == OMX_StateInvalid)
1276 {
1277 CAMHAL_LOGDA("Already in OMX_Loaded state or OMX_StateInvalid state");
1278 return NO_ERROR;
1279 }
1280
1281 if ( 0 != mSwitchToLoadedSem.Count() )
1282 {
1283 CAMHAL_LOGEB("Error mSwitchToLoadedSem semaphore count %d", mSwitchToLoadedSem.Count());
1284 goto EXIT;
1285 }
1286
1287 ///Register for EXECUTING state transition.
1288 ///This method just inserts a message in Event Q, which is checked in the callback
1289 ///The sempahore passed is signalled by the callback
1290 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
1291 OMX_EventCmdComplete,
1292 OMX_CommandStateSet,
1293 OMX_StateIdle,
1294 mSwitchToLoadedSem);
1295
1296 if(ret!=NO_ERROR)
1297 {
1298 CAMHAL_LOGEB("Error in registering for event %d", ret);
1299 goto EXIT;
1300 }
1301
1302 eError = OMX_SendCommand (mCameraAdapterParameters.mHandleComp,
1303 OMX_CommandStateSet,
1304 OMX_StateIdle,
1305 NULL);
1306
1307 if(eError!=OMX_ErrorNone)
1308 {
1309 CAMHAL_LOGEB("OMX_SendCommand(OMX_StateIdle) - %x", eError);
1310 }
1311
1312 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1313
1314 ///Wait for the EXECUTING ->IDLE transition to arrive
1315
1316 CAMHAL_LOGDA("EXECUTING->IDLE state changed");
1317 ret = mSwitchToLoadedSem.WaitTimeout(OMX_CMD_TIMEOUT);
1318
1319 //If somethiing bad happened while we wait
1320 if (mComponentState == OMX_StateInvalid)
1321 {
1322 CAMHAL_LOGEA("Invalid State after EXECUTING->IDLE Exitting!!!");
1323 goto EXIT;
1324 }
1325
1326 if ( NO_ERROR == ret )
1327 {
1328 CAMHAL_LOGDA("EXECUTING->IDLE state changed");
1329 }
1330 else
1331 {
1332 ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
1333 OMX_EventCmdComplete,
1334 OMX_CommandStateSet,
1335 OMX_StateIdle,
1336 NULL);
1337 CAMHAL_LOGEA("Timeout expired on EXECUTING->IDLE state change");
1338 goto EXIT;
1339 }
1340
1341 ///Register for LOADED state transition.
1342 ///This method just inserts a message in Event Q, which is checked in the callback
1343 ///The sempahore passed is signalled by the callback
1344 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
1345 OMX_EventCmdComplete,
1346 OMX_CommandStateSet,
1347 OMX_StateLoaded,
1348 mSwitchToLoadedSem);
1349
1350 if(ret!=NO_ERROR)
1351 {
1352 CAMHAL_LOGEB("Error in registering for event %d", ret);
1353 goto EXIT;
1354 }
1355
1356 eError = OMX_SendCommand (mCameraAdapterParameters.mHandleComp,
1357 OMX_CommandStateSet,
1358 OMX_StateLoaded,
1359 NULL);
1360
1361 if(eError!=OMX_ErrorNone)
1362 {
1363 CAMHAL_LOGEB("OMX_SendCommand(OMX_StateLoaded) - %x", eError);
1364 }
1365 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1366
1367 CAMHAL_LOGDA("Switching IDLE->LOADED state");
1368 ret = mSwitchToLoadedSem.WaitTimeout(OMX_CMD_TIMEOUT);
1369
1370 //If somethiing bad happened while we wait
1371 if (mComponentState == OMX_StateInvalid)
1372 {
1373 CAMHAL_LOGEA("Invalid State after IDLE->LOADED Exitting!!!");
1374 goto EXIT;
1375 }
1376
1377 if ( NO_ERROR == ret )
1378 {
1379 CAMHAL_LOGDA("IDLE->LOADED state changed");
1380 }
1381 else
1382 {
1383 ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
1384 OMX_EventCmdComplete,
1385 OMX_CommandStateSet,
1386 OMX_StateLoaded,
1387 NULL);
1388 CAMHAL_LOGEA("Timeout expired on IDLE->LOADED state change");
1389 goto EXIT;
1390 }
1391
1392 mComponentState = OMX_StateLoaded;
1393
1394 ///Register for Preview port ENABLE event
1395 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
1396 OMX_EventCmdComplete,
1397 OMX_CommandPortEnable,
1398 mCameraAdapterParameters.mPrevPortIndex,
1399 mSwitchToLoadedSem);
1400
1401 if ( NO_ERROR != ret )
1402 {
1403 CAMHAL_LOGEB("Error in registering for event %d", ret);
1404 goto EXIT;
1405 }
1406
1407 ///Enable Preview Port
1408 eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
1409 OMX_CommandPortEnable,
1410 mCameraAdapterParameters.mPrevPortIndex,
1411 NULL);
1412
1413
1414 CAMHAL_LOGDB("OMX_SendCommand(OMX_CommandStateSet) 0x%x", eError);
1415 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1416
1417 CAMHAL_LOGDA("Enabling Preview port");
1418 ///Wait for state to switch to idle
1419 ret = mSwitchToLoadedSem.WaitTimeout(OMX_CMD_TIMEOUT);
1420
1421 //If somethiing bad happened while we wait
1422 if (mComponentState == OMX_StateInvalid)
1423 {
1424 CAMHAL_LOGEA("Invalid State after Enabling Preview port Exitting!!!");
1425 goto EXIT;
1426 }
1427
1428 if ( NO_ERROR == ret )
1429 {
1430 CAMHAL_LOGDA("Preview port enabled!");
1431 }
1432 else
1433 {
1434 ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
1435 OMX_EventCmdComplete,
1436 OMX_CommandPortEnable,
1437 mCameraAdapterParameters.mPrevPortIndex,
1438 NULL);
1439 CAMHAL_LOGEA("Preview enable timedout");
1440
1441 goto EXIT;
1442 }
1443
1444 return (ret | ErrorUtils::omxToAndroidError(eError));
1445
1446 EXIT:
1447 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
1448 performCleanupAfterError();
1449 LOG_FUNCTION_NAME_EXIT;
1450 return (ret | ErrorUtils::omxToAndroidError(eError));
1451 }
1452
UseBuffersPreview(void * bufArr,int num)1453 status_t OMXCameraAdapter::UseBuffersPreview(void* bufArr, int num)
1454 {
1455 status_t ret = NO_ERROR;
1456 OMX_ERRORTYPE eError = OMX_ErrorNone;
1457 int tmpHeight, tmpWidth;
1458
1459 LOG_FUNCTION_NAME;
1460
1461 ///Flag to determine whether it is 3D camera or not
1462 bool isS3d = false;
1463 const char *valstr = NULL;
1464 if ( (valstr = mParams.get(TICameraParameters::KEY_S3D_SUPPORTED)) != NULL) {
1465 isS3d = (strcmp(valstr, "true") == 0);
1466 }
1467
1468 if(!bufArr)
1469 {
1470 CAMHAL_LOGEA("NULL pointer passed for buffArr");
1471 LOG_FUNCTION_NAME_EXIT;
1472 return BAD_VALUE;
1473 }
1474
1475 OMXCameraPortParameters * mPreviewData = NULL;
1476 OMXCameraPortParameters *measurementData = NULL;
1477 mPreviewData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex];
1478 measurementData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mMeasurementPortIndex];
1479 mPreviewData->mNumBufs = num ;
1480 uint32_t *buffers = (uint32_t*)bufArr;
1481
1482 if ( 0 != mUsePreviewSem.Count() )
1483 {
1484 CAMHAL_LOGEB("Error mUsePreviewSem semaphore count %d", mUsePreviewSem.Count());
1485 LOG_FUNCTION_NAME_EXIT;
1486 return NO_INIT;
1487 }
1488
1489 if(mPreviewData->mNumBufs != num)
1490 {
1491 CAMHAL_LOGEA("Current number of buffers doesnt equal new num of buffers passed!");
1492 LOG_FUNCTION_NAME_EXIT;
1493 return BAD_VALUE;
1494 }
1495
1496 mStateSwitchLock.lock();
1497
1498 if ( mComponentState == OMX_StateLoaded )
1499 {
1500
1501 ret = setLDC(mIPP);
1502 if ( NO_ERROR != ret )
1503 {
1504 CAMHAL_LOGEB("setLDC() failed %d", ret);
1505 LOG_FUNCTION_NAME_EXIT;
1506 return ret;
1507 }
1508
1509 ret = setNSF(mIPP);
1510 if ( NO_ERROR != ret )
1511 {
1512 CAMHAL_LOGEB("setNSF() failed %d", ret);
1513 LOG_FUNCTION_NAME_EXIT;
1514 return ret;
1515 }
1516
1517 ret = setCaptureMode(mCapMode);
1518 if ( NO_ERROR != ret )
1519 {
1520 CAMHAL_LOGEB("setCaptureMode() failed %d", ret);
1521 LOG_FUNCTION_NAME_EXIT;
1522 return ret;
1523 }
1524
1525 CAMHAL_LOGDB("Camera Mode = %d", mCapMode);
1526
1527 if( ( mCapMode == OMXCameraAdapter::VIDEO_MODE ) ||
1528 ( isS3d && (mCapMode == OMXCameraAdapter::HIGH_QUALITY)) )
1529 {
1530 ///Enable/Disable Video Noise Filter
1531 ret = enableVideoNoiseFilter(mVnfEnabled);
1532 if ( NO_ERROR != ret)
1533 {
1534 CAMHAL_LOGEB("Error configuring VNF %x", ret);
1535 return ret;
1536 }
1537
1538 ///Enable/Disable Video Stabilization
1539 ret = enableVideoStabilization(mVstabEnabled);
1540 if ( NO_ERROR != ret)
1541 {
1542 CAMHAL_LOGEB("Error configuring VSTAB %x", ret);
1543 return ret;
1544 }
1545 }
1546 else
1547 {
1548 ret = enableVideoNoiseFilter(false);
1549 if ( NO_ERROR != ret)
1550 {
1551 CAMHAL_LOGEB("Error configuring VNF %x", ret);
1552 return ret;
1553 }
1554 ///Enable/Disable Video Stabilization
1555 ret = enableVideoStabilization(false);
1556 if ( NO_ERROR != ret)
1557 {
1558 CAMHAL_LOGEB("Error configuring VSTAB %x", ret);
1559 return ret;
1560 }
1561 }
1562 }
1563
1564 ret = setSensorOrientation(mSensorOrientation);
1565 if ( NO_ERROR != ret )
1566 {
1567 CAMHAL_LOGEB("Error configuring Sensor Orientation %x", ret);
1568 mSensorOrientation = 0;
1569 }
1570
1571 ret = setVFramerate(mPreviewData->mMinFrameRate, mPreviewData->mMaxFrameRate);
1572 if ( ret != NO_ERROR )
1573 {
1574 CAMHAL_LOGEB("VFR configuration failed 0x%x", ret);
1575 LOG_FUNCTION_NAME_EXIT;
1576 return ret;
1577 }
1578
1579 if ( mComponentState == OMX_StateLoaded )
1580 {
1581 ///Register for IDLE state switch event
1582 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
1583 OMX_EventCmdComplete,
1584 OMX_CommandStateSet,
1585 OMX_StateIdle,
1586 mUsePreviewSem);
1587
1588 if(ret!=NO_ERROR)
1589 {
1590 CAMHAL_LOGEB("Error in registering for event %d", ret);
1591 goto EXIT;
1592 }
1593
1594 ///Once we get the buffers, move component state to idle state and pass the buffers to OMX comp using UseBuffer
1595 eError = OMX_SendCommand (mCameraAdapterParameters.mHandleComp ,
1596 OMX_CommandStateSet,
1597 OMX_StateIdle,
1598 NULL);
1599
1600 CAMHAL_LOGDB("OMX_SendCommand(OMX_CommandStateSet) 0x%x", eError);
1601
1602 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1603
1604 mComponentState = OMX_StateIdle;
1605 }
1606 else
1607 {
1608 ///Register for Preview port ENABLE event
1609 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
1610 OMX_EventCmdComplete,
1611 OMX_CommandPortEnable,
1612 mCameraAdapterParameters.mPrevPortIndex,
1613 mUsePreviewSem);
1614
1615 if ( NO_ERROR != ret )
1616 {
1617 CAMHAL_LOGEB("Error in registering for event %d", ret);
1618 goto EXIT;
1619 }
1620
1621 ///Enable Preview Port
1622 eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
1623 OMX_CommandPortEnable,
1624 mCameraAdapterParameters.mPrevPortIndex,
1625 NULL);
1626 }
1627
1628
1629 ///Configure DOMX to use either gralloc handles or vptrs
1630 OMX_TI_PARAMUSENATIVEBUFFER domxUseGrallocHandles;
1631 OMX_INIT_STRUCT_PTR (&domxUseGrallocHandles, OMX_TI_PARAMUSENATIVEBUFFER);
1632
1633 domxUseGrallocHandles.nPortIndex = mCameraAdapterParameters.mPrevPortIndex;
1634 domxUseGrallocHandles.bEnable = OMX_TRUE;
1635
1636 eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp,
1637 (OMX_INDEXTYPE)OMX_TI_IndexUseNativeBuffers, &domxUseGrallocHandles);
1638 if(eError!=OMX_ErrorNone)
1639 {
1640 CAMHAL_LOGEB("OMX_SetParameter - %x", eError);
1641 }
1642 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1643
1644 OMX_BUFFERHEADERTYPE *pBufferHdr;
1645 for(int index=0;index<num;index++) {
1646
1647 CAMHAL_LOGDB("OMX_UseBuffer(0x%x)", buffers[index]);
1648 eError = OMX_UseBuffer( mCameraAdapterParameters.mHandleComp,
1649 &pBufferHdr,
1650 mCameraAdapterParameters.mPrevPortIndex,
1651 0,
1652 mPreviewData->mBufSize,
1653 (OMX_U8*)buffers[index]);
1654 if(eError!=OMX_ErrorNone)
1655 {
1656 CAMHAL_LOGEB("OMX_UseBuffer-0x%x", eError);
1657 }
1658 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1659
1660 //pBufferHdr->pAppPrivate = (OMX_PTR)pBufferHdr;
1661 pBufferHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
1662 pBufferHdr->nVersion.s.nVersionMajor = 1 ;
1663 pBufferHdr->nVersion.s.nVersionMinor = 1 ;
1664 pBufferHdr->nVersion.s.nRevision = 0 ;
1665 pBufferHdr->nVersion.s.nStep = 0;
1666 mPreviewData->mBufferHeader[index] = pBufferHdr;
1667 }
1668
1669 if ( mMeasurementEnabled )
1670 {
1671
1672 for( int i = 0; i < num; i++ )
1673 {
1674 OMX_BUFFERHEADERTYPE *pBufHdr;
1675 eError = OMX_UseBuffer( mCameraAdapterParameters.mHandleComp,
1676 &pBufHdr,
1677 mCameraAdapterParameters.mMeasurementPortIndex,
1678 0,
1679 measurementData->mBufSize,
1680 (OMX_U8*)(mPreviewDataBuffers[i]));
1681
1682 if ( eError == OMX_ErrorNone )
1683 {
1684 pBufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
1685 pBufHdr->nVersion.s.nVersionMajor = 1 ;
1686 pBufHdr->nVersion.s.nVersionMinor = 1 ;
1687 pBufHdr->nVersion.s.nRevision = 0 ;
1688 pBufHdr->nVersion.s.nStep = 0;
1689 measurementData->mBufferHeader[i] = pBufHdr;
1690 }
1691 else
1692 {
1693 CAMHAL_LOGEB("OMX_UseBuffer -0x%x", eError);
1694 ret = BAD_VALUE;
1695 break;
1696 }
1697 }
1698
1699 }
1700
1701 CAMHAL_LOGDA("Registering preview buffers");
1702
1703 ret = mUsePreviewSem.WaitTimeout(OMX_CMD_TIMEOUT);
1704
1705 //If somethiing bad happened while we wait
1706 if (mComponentState == OMX_StateInvalid)
1707 {
1708 CAMHAL_LOGEA("Invalid State after Registering preview buffers Exitting!!!");
1709 goto EXIT;
1710 }
1711
1712 if ( NO_ERROR == ret )
1713 {
1714 CAMHAL_LOGDA("Preview buffer registration successfull");
1715 }
1716 else
1717 {
1718 if ( mComponentState == OMX_StateLoaded )
1719 {
1720 ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
1721 OMX_EventCmdComplete,
1722 OMX_CommandStateSet,
1723 OMX_StateIdle,
1724 NULL);
1725 }
1726 else
1727 {
1728 ret |= SignalEvent(mCameraAdapterParameters.mHandleComp,
1729 OMX_EventCmdComplete,
1730 OMX_CommandPortEnable,
1731 mCameraAdapterParameters.mPrevPortIndex,
1732 NULL);
1733 }
1734 CAMHAL_LOGEA("Timeout expired on preview buffer registration");
1735 goto EXIT;
1736 }
1737
1738 LOG_FUNCTION_NAME_EXIT;
1739
1740 return (ret | ErrorUtils::omxToAndroidError(eError));
1741
1742 ///If there is any failure, we reach here.
1743 ///Here, we do any resource freeing and convert from OMX error code to Camera Hal error code
1744 EXIT:
1745 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
1746 performCleanupAfterError();
1747 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
1748
1749 LOG_FUNCTION_NAME_EXIT;
1750
1751 return (ret | ErrorUtils::omxToAndroidError(eError));
1752 }
1753
startPreview()1754 status_t OMXCameraAdapter::startPreview()
1755 {
1756 status_t ret = NO_ERROR;
1757 OMX_ERRORTYPE eError = OMX_ErrorNone;
1758 OMXCameraPortParameters *mPreviewData = NULL;
1759 OMXCameraPortParameters *measurementData = NULL;
1760
1761 LOG_FUNCTION_NAME;
1762
1763 if( 0 != mStartPreviewSem.Count() )
1764 {
1765 CAMHAL_LOGEB("Error mStartPreviewSem semaphore count %d", mStartPreviewSem.Count());
1766 LOG_FUNCTION_NAME_EXIT;
1767 return NO_INIT;
1768 }
1769
1770 mPreviewData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex];
1771 measurementData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mMeasurementPortIndex];
1772
1773 if( OMX_StateIdle == mComponentState )
1774 {
1775 ///Register for EXECUTING state transition.
1776 ///This method just inserts a message in Event Q, which is checked in the callback
1777 ///The sempahore passed is signalled by the callback
1778 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
1779 OMX_EventCmdComplete,
1780 OMX_CommandStateSet,
1781 OMX_StateExecuting,
1782 mStartPreviewSem);
1783
1784 if(ret!=NO_ERROR)
1785 {
1786 CAMHAL_LOGEB("Error in registering for event %d", ret);
1787 goto EXIT;
1788 }
1789
1790 ///Switch to EXECUTING state
1791 eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
1792 OMX_CommandStateSet,
1793 OMX_StateExecuting,
1794 NULL);
1795
1796 if(eError!=OMX_ErrorNone)
1797 {
1798 CAMHAL_LOGEB("OMX_SendCommand(OMX_StateExecuting)-0x%x", eError);
1799 }
1800
1801 CAMHAL_LOGDA("+Waiting for component to go into EXECUTING state");
1802 ret = mStartPreviewSem.WaitTimeout(OMX_CMD_TIMEOUT);
1803
1804 //If somethiing bad happened while we wait
1805 if (mComponentState == OMX_StateInvalid)
1806 {
1807 CAMHAL_LOGEA("Invalid State after IDLE_EXECUTING Exitting!!!");
1808 goto EXIT;
1809 }
1810
1811 if ( NO_ERROR == ret )
1812 {
1813 CAMHAL_LOGDA("+Great. Component went into executing state!!");
1814 }
1815 else
1816 {
1817 ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
1818 OMX_EventCmdComplete,
1819 OMX_CommandStateSet,
1820 OMX_StateExecuting,
1821 NULL);
1822 CAMHAL_LOGDA("Timeout expired on executing state switch!");
1823 goto EXIT;
1824 }
1825
1826 mComponentState = OMX_StateExecuting;
1827
1828 }
1829
1830 mStateSwitchLock.unlock();
1831
1832 //Queue all the buffers on preview port
1833 for(int index=0;index< mPreviewData->mMaxQueueable;index++)
1834 {
1835 CAMHAL_LOGDB("Queuing buffer on Preview port - 0x%x", (uint32_t)mPreviewData->mBufferHeader[index]->pBuffer);
1836 eError = OMX_FillThisBuffer(mCameraAdapterParameters.mHandleComp,
1837 (OMX_BUFFERHEADERTYPE*)mPreviewData->mBufferHeader[index]);
1838 if(eError!=OMX_ErrorNone)
1839 {
1840 CAMHAL_LOGEB("OMX_FillThisBuffer-0x%x", eError);
1841 }
1842 mFramesWithDucati++;
1843 #ifdef DEGUG_LOG
1844 mBuffersWithDucati.add((uint32_t)mPreviewData->mBufferHeader[index]->pBuffer,1);
1845 #endif
1846 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1847 }
1848
1849 if ( mMeasurementEnabled )
1850 {
1851
1852 for(int index=0;index< mPreviewData->mNumBufs;index++)
1853 {
1854 CAMHAL_LOGDB("Queuing buffer on Measurement port - 0x%x", (uint32_t) measurementData->mBufferHeader[index]->pBuffer);
1855 eError = OMX_FillThisBuffer(mCameraAdapterParameters.mHandleComp,
1856 (OMX_BUFFERHEADERTYPE*) measurementData->mBufferHeader[index]);
1857 if(eError!=OMX_ErrorNone)
1858 {
1859 CAMHAL_LOGEB("OMX_FillThisBuffer-0x%x", eError);
1860 }
1861 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1862 }
1863
1864 }
1865
1866 if ( mPending3Asettings )
1867 apply3Asettings(mParameters3A);
1868
1869 //reset frame rate estimates
1870 mFPS = 0.0f;
1871 mLastFPS = 0.0f;
1872 // start frame count from 0. i.e first frame after
1873 // startPreview will be the 0th reference frame
1874 // this way we will wait for second frame until
1875 // takePicture/autoFocus is allowed to run. we
1876 // are seeing SetConfig/GetConfig fail after
1877 // calling after the first frame and not failing
1878 // after the second frame
1879 mFrameCount = -1;
1880 mLastFrameCount = 0;
1881 mIter = 1;
1882 mLastFPSTime = systemTime();
1883
1884 LOG_FUNCTION_NAME_EXIT;
1885
1886 return (ret | ErrorUtils::omxToAndroidError(eError));
1887
1888 EXIT:
1889
1890 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
1891 performCleanupAfterError();
1892 mStateSwitchLock.unlock();
1893 LOG_FUNCTION_NAME_EXIT;
1894
1895 return (ret | ErrorUtils::omxToAndroidError(eError));
1896
1897 }
1898
stopPreview()1899 status_t OMXCameraAdapter::stopPreview()
1900 {
1901 LOG_FUNCTION_NAME;
1902
1903 OMX_ERRORTYPE eError = OMX_ErrorNone;
1904 status_t ret = NO_ERROR;
1905
1906 OMXCameraPortParameters *mCaptureData , *mPreviewData, *measurementData;
1907 mCaptureData = mPreviewData = measurementData = NULL;
1908
1909 mPreviewData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex];
1910 mCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
1911 measurementData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mMeasurementPortIndex];
1912
1913 if ( mComponentState != OMX_StateExecuting )
1914 {
1915 CAMHAL_LOGEA("Calling StopPreview() when not in EXECUTING state");
1916 LOG_FUNCTION_NAME_EXIT;
1917 return NO_INIT;
1918 }
1919
1920 {
1921 Mutex::Autolock lock(mFrameCountMutex);
1922 mFrameCount = 0;
1923 mFirstFrameCondition.broadcast();
1924 }
1925
1926 ret = cancelAutoFocus();
1927 if(ret!=NO_ERROR)
1928 {
1929 CAMHAL_LOGEB("Error canceling autofocus %d", ret);
1930 // Error, but we probably still want to continue to stop preview
1931 }
1932
1933 OMX_CONFIG_FOCUSASSISTTYPE focusAssist;
1934 OMX_INIT_STRUCT_PTR (&focusAssist, OMX_CONFIG_FOCUSASSISTTYPE);
1935 focusAssist.nPortIndex = OMX_ALL;
1936 focusAssist.bFocusAssist = OMX_FALSE;
1937 CAMHAL_LOGDB("Configuring AF Assist mode 0x%x", focusAssist.bFocusAssist);
1938 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
1939 (OMX_INDEXTYPE) OMX_IndexConfigFocusAssist,
1940 &focusAssist);
1941 if ( OMX_ErrorNone != eError )
1942 {
1943 CAMHAL_LOGEB("Error while configuring AF Assist mode 0x%x", eError);
1944 }
1945 else
1946 {
1947 CAMHAL_LOGDA("Camera AF Assist mode configured successfully");
1948 }
1949
1950 if ( 0 != mStopPreviewSem.Count() )
1951 {
1952 CAMHAL_LOGEB("Error mStopPreviewSem semaphore count %d", mStopPreviewSem.Count());
1953 LOG_FUNCTION_NAME_EXIT;
1954 return NO_INIT;
1955 }
1956
1957 ret = disableImagePort();
1958 if ( NO_ERROR != ret ) {
1959 CAMHAL_LOGEB("disable image port failed 0x%x", ret);
1960 goto EXIT;
1961 }
1962
1963 CAMHAL_LOGDB("Average framerate: %f", mFPS);
1964
1965 //Avoid state switching of the OMX Component
1966 ret = flushBuffers();
1967 if ( NO_ERROR != ret )
1968 {
1969 CAMHAL_LOGEB("Flush Buffers failed 0x%x", ret);
1970 goto EXIT;
1971 }
1972
1973 ///Register for Preview port Disable event
1974 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
1975 OMX_EventCmdComplete,
1976 OMX_CommandPortDisable,
1977 mCameraAdapterParameters.mPrevPortIndex,
1978 mStopPreviewSem);
1979
1980 ///Disable Preview Port
1981 eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
1982 OMX_CommandPortDisable,
1983 mCameraAdapterParameters.mPrevPortIndex,
1984 NULL);
1985
1986 ///Free the OMX Buffers
1987 for ( int i = 0 ; i < mPreviewData->mNumBufs ; i++ )
1988 {
1989 eError = OMX_FreeBuffer(mCameraAdapterParameters.mHandleComp,
1990 mCameraAdapterParameters.mPrevPortIndex,
1991 mPreviewData->mBufferHeader[i]);
1992
1993 if(eError!=OMX_ErrorNone)
1994 {
1995 CAMHAL_LOGEB("OMX_FreeBuffer - %x", eError);
1996 }
1997 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
1998 }
1999
2000 if ( mMeasurementEnabled )
2001 {
2002
2003 for ( int i = 0 ; i < measurementData->mNumBufs ; i++ )
2004 {
2005 eError = OMX_FreeBuffer(mCameraAdapterParameters.mHandleComp,
2006 mCameraAdapterParameters.mMeasurementPortIndex,
2007 measurementData->mBufferHeader[i]);
2008 if(eError!=OMX_ErrorNone)
2009 {
2010 CAMHAL_LOGEB("OMX_FreeBuffer - %x", eError);
2011 }
2012 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
2013 }
2014
2015 {
2016 Mutex::Autolock lock(mPreviewDataBufferLock);
2017 mPreviewDataBuffersAvailable.clear();
2018 }
2019
2020 }
2021
2022 CAMHAL_LOGDA("Disabling preview port");
2023 ret = mStopPreviewSem.WaitTimeout(OMX_CMD_TIMEOUT);
2024
2025 //If somethiing bad happened while we wait
2026 if (mComponentState == OMX_StateInvalid)
2027 {
2028 CAMHAL_LOGEA("Invalid State after Disabling preview port Exitting!!!");
2029 goto EXIT;
2030 }
2031
2032 if ( NO_ERROR == ret )
2033 {
2034 CAMHAL_LOGDA("Preview port disabled");
2035 }
2036 else
2037 {
2038 ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
2039 OMX_EventCmdComplete,
2040 OMX_CommandPortDisable,
2041 mCameraAdapterParameters.mPrevPortIndex,
2042 NULL);
2043 CAMHAL_LOGEA("Timeout expired on preview port disable");
2044 goto EXIT;
2045 }
2046
2047 {
2048 Mutex::Autolock lock(mPreviewBufferLock);
2049 ///Clear all the available preview buffers
2050 mPreviewBuffersAvailable.clear();
2051 }
2052
2053 switchToLoaded();
2054
2055
2056 mFirstTimeInit = true;
2057 mPendingCaptureSettings = 0;
2058 mFramesWithDucati = 0;
2059 mFramesWithDisplay = 0;
2060 mFramesWithEncoder = 0;
2061
2062 LOG_FUNCTION_NAME_EXIT;
2063
2064 return (ret | ErrorUtils::omxToAndroidError(eError));
2065
2066 EXIT:
2067 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
2068 {
2069 Mutex::Autolock lock(mPreviewBufferLock);
2070 ///Clear all the available preview buffers
2071 mPreviewBuffersAvailable.clear();
2072 }
2073 performCleanupAfterError();
2074 LOG_FUNCTION_NAME_EXIT;
2075 return (ret | ErrorUtils::omxToAndroidError(eError));
2076
2077 }
2078
setSensorOverclock(bool enable)2079 status_t OMXCameraAdapter::setSensorOverclock(bool enable)
2080 {
2081 status_t ret = NO_ERROR;
2082 OMX_ERRORTYPE eError = OMX_ErrorNone;
2083 OMX_CONFIG_BOOLEANTYPE bOMX;
2084
2085 LOG_FUNCTION_NAME;
2086
2087 if ( OMX_StateLoaded != mComponentState )
2088 {
2089 CAMHAL_LOGDA("OMX component is not in loaded state");
2090 return ret;
2091 }
2092
2093 if ( NO_ERROR == ret )
2094 {
2095 OMX_INIT_STRUCT_PTR (&bOMX, OMX_CONFIG_BOOLEANTYPE);
2096
2097 if ( enable )
2098 {
2099 bOMX.bEnabled = OMX_TRUE;
2100 }
2101 else
2102 {
2103 bOMX.bEnabled = OMX_FALSE;
2104 }
2105
2106 CAMHAL_LOGDB("Configuring Sensor overclock mode 0x%x", bOMX.bEnabled);
2107 eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp, ( OMX_INDEXTYPE ) OMX_TI_IndexParamSensorOverClockMode, &bOMX);
2108 if ( OMX_ErrorNone != eError )
2109 {
2110 CAMHAL_LOGEB("Error while setting Sensor overclock 0x%x", eError);
2111 ret = BAD_VALUE;
2112 }
2113 else
2114 {
2115 mSensorOverclock = enable;
2116 }
2117 }
2118
2119 LOG_FUNCTION_NAME_EXIT;
2120
2121 return ret;
2122 }
2123
printComponentVersion(OMX_HANDLETYPE handle)2124 status_t OMXCameraAdapter::printComponentVersion(OMX_HANDLETYPE handle)
2125 {
2126 status_t ret = NO_ERROR;
2127 OMX_ERRORTYPE eError = OMX_ErrorNone;
2128 OMX_VERSIONTYPE compVersion;
2129 char compName[OMX_MAX_STRINGNAME_SIZE];
2130 char *currentUUID = NULL;
2131 size_t offset = 0;
2132
2133 LOG_FUNCTION_NAME;
2134
2135 if ( NULL == handle )
2136 {
2137 CAMHAL_LOGEB("Invalid OMX Handle =0x%x", ( unsigned int ) handle);
2138 ret = -EINVAL;
2139 }
2140
2141 mCompUUID[0] = 0;
2142
2143 if ( NO_ERROR == ret )
2144 {
2145 eError = OMX_GetComponentVersion(handle,
2146 compName,
2147 &compVersion,
2148 &mCompRevision,
2149 &mCompUUID
2150 );
2151 if ( OMX_ErrorNone != eError )
2152 {
2153 CAMHAL_LOGEB("OMX_GetComponentVersion returned 0x%x", eError);
2154 ret = BAD_VALUE;
2155 }
2156 }
2157
2158 if ( NO_ERROR == ret )
2159 {
2160 CAMHAL_LOGVB("OMX Component name: [%s]", compName);
2161 CAMHAL_LOGVB("OMX Component version: [%u]", ( unsigned int ) compVersion.nVersion);
2162 CAMHAL_LOGVB("Spec version: [%u]", ( unsigned int ) mCompRevision.nVersion);
2163 CAMHAL_LOGVB("Git Commit ID: [%s]", mCompUUID);
2164 currentUUID = ( char * ) mCompUUID;
2165 }
2166
2167 if ( NULL != currentUUID )
2168 {
2169 offset = strlen( ( const char * ) mCompUUID) + 1;
2170 if ( (int)currentUUID + (int)offset - (int)mCompUUID < OMX_MAX_STRINGNAME_SIZE )
2171 {
2172 currentUUID += offset;
2173 CAMHAL_LOGVB("Git Branch: [%s]", currentUUID);
2174 }
2175 else
2176 {
2177 ret = BAD_VALUE;
2178 }
2179 }
2180
2181 if ( NO_ERROR == ret )
2182 {
2183 offset = strlen( ( const char * ) currentUUID) + 1;
2184
2185 if ( (int)currentUUID + (int)offset - (int)mCompUUID < OMX_MAX_STRINGNAME_SIZE )
2186 {
2187 currentUUID += offset;
2188 CAMHAL_LOGVB("Build date and time: [%s]", currentUUID);
2189 }
2190 else
2191 {
2192 ret = BAD_VALUE;
2193 }
2194 }
2195
2196 if ( NO_ERROR == ret )
2197 {
2198 offset = strlen( ( const char * ) currentUUID) + 1;
2199
2200 if ( (int)currentUUID + (int)offset - (int)mCompUUID < OMX_MAX_STRINGNAME_SIZE )
2201 {
2202 currentUUID += offset;
2203 CAMHAL_LOGVB("Build description: [%s]", currentUUID);
2204 }
2205 else
2206 {
2207 ret = BAD_VALUE;
2208 }
2209 }
2210
2211 LOG_FUNCTION_NAME_EXIT;
2212
2213 return ret;
2214 }
2215
autoFocus()2216 status_t OMXCameraAdapter::autoFocus()
2217 {
2218 status_t ret = NO_ERROR;
2219 TIUTILS::Message msg;
2220
2221 LOG_FUNCTION_NAME;
2222
2223 {
2224 Mutex::Autolock lock(mFrameCountMutex);
2225 if (mFrameCount < 1) {
2226 // first frame may time some time to come...so wait for an adequate amount of time
2227 // which 2 * OMX_CAPTURE_TIMEOUT * 1000 will cover.
2228 ret = mFirstFrameCondition.waitRelative(mFrameCountMutex,
2229 (nsecs_t) 2 * OMX_CAPTURE_TIMEOUT * 1000);
2230 if ((NO_ERROR != ret) || (mFrameCount == 0)) {
2231 goto EXIT;
2232 }
2233 }
2234 }
2235
2236 msg.command = CommandHandler::CAMERA_PERFORM_AUTOFOCUS;
2237 msg.arg1 = mErrorNotifier;
2238 ret = mCommandHandler->put(&msg);
2239
2240 EXIT:
2241
2242 LOG_FUNCTION_NAME;
2243
2244 return ret;
2245 }
2246
takePicture()2247 status_t OMXCameraAdapter::takePicture()
2248 {
2249 status_t ret = NO_ERROR;
2250 TIUTILS::Message msg;
2251
2252 LOG_FUNCTION_NAME;
2253
2254 {
2255 Mutex::Autolock lock(mFrameCountMutex);
2256 if (mFrameCount < 1) {
2257 // first frame may time some time to come...so wait for an adequate amount of time
2258 // which 2 * OMX_CAPTURE_TIMEOUT * 1000 will cover.
2259 ret = mFirstFrameCondition.waitRelative(mFrameCountMutex,
2260 (nsecs_t) 2 * OMX_CAPTURE_TIMEOUT * 1000);
2261 if ((NO_ERROR != ret) || (mFrameCount == 0)) {
2262 goto EXIT;
2263 }
2264 }
2265 }
2266
2267 msg.command = CommandHandler::CAMERA_START_IMAGE_CAPTURE;
2268 msg.arg1 = mErrorNotifier;
2269 ret = mCommandHandler->put(&msg);
2270
2271 EXIT:
2272 LOG_FUNCTION_NAME_EXIT;
2273
2274 return ret;
2275 }
2276
startVideoCapture()2277 status_t OMXCameraAdapter::startVideoCapture()
2278 {
2279 return BaseCameraAdapter::startVideoCapture();
2280 }
2281
stopVideoCapture()2282 status_t OMXCameraAdapter::stopVideoCapture()
2283 {
2284 return BaseCameraAdapter::stopVideoCapture();
2285 }
2286
2287 //API to get the frame size required to be allocated. This size is used to override the size passed
2288 //by camera service when VSTAB/VNF is turned ON for example
getFrameSize(size_t & width,size_t & height)2289 status_t OMXCameraAdapter::getFrameSize(size_t &width, size_t &height)
2290 {
2291 status_t ret = NO_ERROR;
2292 OMX_ERRORTYPE eError = OMX_ErrorNone;
2293 OMX_CONFIG_RECTTYPE tFrameDim;
2294
2295 LOG_FUNCTION_NAME;
2296
2297 OMX_INIT_STRUCT_PTR (&tFrameDim, OMX_CONFIG_RECTTYPE);
2298 tFrameDim.nPortIndex = mCameraAdapterParameters.mPrevPortIndex;
2299
2300 if ( mOMXStateSwitch )
2301 {
2302 ret = switchToLoaded();
2303 if ( NO_ERROR != ret )
2304 {
2305 CAMHAL_LOGEB("switchToLoaded() failed 0x%x", ret);
2306 goto exit;
2307 }
2308
2309 mOMXStateSwitch = false;
2310 }
2311
2312 if ( OMX_StateLoaded == mComponentState )
2313 {
2314
2315 ret = setLDC(mIPP);
2316 if ( NO_ERROR != ret )
2317 {
2318 CAMHAL_LOGEB("setLDC() failed %d", ret);
2319 LOG_FUNCTION_NAME_EXIT;
2320 goto exit;
2321 }
2322
2323 ret = setNSF(mIPP);
2324 if ( NO_ERROR != ret )
2325 {
2326 CAMHAL_LOGEB("setNSF() failed %d", ret);
2327 LOG_FUNCTION_NAME_EXIT;
2328 goto exit;
2329 }
2330
2331 ret = setCaptureMode(mCapMode);
2332 if ( NO_ERROR != ret )
2333 {
2334 CAMHAL_LOGEB("setCaptureMode() failed %d", ret);
2335 }
2336
2337 if(mCapMode == OMXCameraAdapter::VIDEO_MODE)
2338 {
2339 if ( NO_ERROR == ret )
2340 {
2341 ///Enable/Disable Video Noise Filter
2342 ret = enableVideoNoiseFilter(mVnfEnabled);
2343 }
2344
2345 if ( NO_ERROR != ret)
2346 {
2347 CAMHAL_LOGEB("Error configuring VNF %x", ret);
2348 }
2349
2350 if ( NO_ERROR == ret )
2351 {
2352 ///Enable/Disable Video Stabilization
2353 ret = enableVideoStabilization(mVstabEnabled);
2354 }
2355
2356 if ( NO_ERROR != ret)
2357 {
2358 CAMHAL_LOGEB("Error configuring VSTAB %x", ret);
2359 }
2360 }
2361 else
2362 {
2363 if ( NO_ERROR == ret )
2364 {
2365 ///Enable/Disable Video Noise Filter
2366 ret = enableVideoNoiseFilter(false);
2367 }
2368
2369 if ( NO_ERROR != ret)
2370 {
2371 CAMHAL_LOGEB("Error configuring VNF %x", ret);
2372 }
2373
2374 if ( NO_ERROR == ret )
2375 {
2376 ///Enable/Disable Video Stabilization
2377 ret = enableVideoStabilization(false);
2378 }
2379
2380 if ( NO_ERROR != ret)
2381 {
2382 CAMHAL_LOGEB("Error configuring VSTAB %x", ret);
2383 }
2384 }
2385
2386 }
2387
2388 ret = setSensorOrientation(mSensorOrientation);
2389 if ( NO_ERROR != ret )
2390 {
2391 CAMHAL_LOGEB("Error configuring Sensor Orientation %x", ret);
2392 mSensorOrientation = 0;
2393 }
2394
2395 if ( NO_ERROR == ret )
2396 {
2397 eError = OMX_GetParameter(mCameraAdapterParameters.mHandleComp, ( OMX_INDEXTYPE ) OMX_TI_IndexParam2DBufferAllocDimension, &tFrameDim);
2398 if ( OMX_ErrorNone == eError)
2399 {
2400 width = tFrameDim.nWidth;
2401 height = tFrameDim.nHeight;
2402 }
2403 }
2404
2405 exit:
2406
2407 CAMHAL_LOGDB("Required frame size %dx%d", width, height);
2408 LOG_FUNCTION_NAME_EXIT;
2409
2410 return ret;
2411 }
2412
getFrameDataSize(size_t & dataFrameSize,size_t bufferCount)2413 status_t OMXCameraAdapter::getFrameDataSize(size_t &dataFrameSize, size_t bufferCount)
2414 {
2415 status_t ret = NO_ERROR;
2416 OMX_PARAM_PORTDEFINITIONTYPE portCheck;
2417 OMX_ERRORTYPE eError = OMX_ErrorNone;
2418
2419 LOG_FUNCTION_NAME;
2420
2421 if ( OMX_StateLoaded != mComponentState )
2422 {
2423 CAMHAL_LOGEA("Calling getFrameDataSize() when not in LOADED state");
2424 dataFrameSize = 0;
2425 ret = BAD_VALUE;
2426 }
2427
2428 if ( NO_ERROR == ret )
2429 {
2430 OMX_INIT_STRUCT_PTR(&portCheck, OMX_PARAM_PORTDEFINITIONTYPE);
2431 portCheck.nPortIndex = mCameraAdapterParameters.mMeasurementPortIndex;
2432
2433 eError = OMX_GetParameter(mCameraAdapterParameters.mHandleComp, OMX_IndexParamPortDefinition, &portCheck);
2434 if ( OMX_ErrorNone != eError )
2435 {
2436 CAMHAL_LOGEB("OMX_GetParameter on OMX_IndexParamPortDefinition returned: 0x%x", eError);
2437 dataFrameSize = 0;
2438 ret = BAD_VALUE;
2439 }
2440 }
2441
2442 if ( NO_ERROR == ret )
2443 {
2444 portCheck.nBufferCountActual = bufferCount;
2445 eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp, OMX_IndexParamPortDefinition, &portCheck);
2446 if ( OMX_ErrorNone != eError )
2447 {
2448 CAMHAL_LOGEB("OMX_SetParameter on OMX_IndexParamPortDefinition returned: 0x%x", eError);
2449 dataFrameSize = 0;
2450 ret = BAD_VALUE;
2451 }
2452 }
2453
2454 if ( NO_ERROR == ret )
2455 {
2456 eError = OMX_GetParameter(mCameraAdapterParameters.mHandleComp, OMX_IndexParamPortDefinition, &portCheck);
2457 if ( OMX_ErrorNone != eError )
2458 {
2459 CAMHAL_LOGEB("OMX_GetParameter on OMX_IndexParamPortDefinition returned: 0x%x", eError);
2460 ret = BAD_VALUE;
2461 }
2462 else
2463 {
2464 mCameraAdapterParameters.mCameraPortParams[portCheck.nPortIndex].mBufSize = portCheck.nBufferSize;
2465 dataFrameSize = portCheck.nBufferSize;
2466 }
2467 }
2468
2469 LOG_FUNCTION_NAME_EXIT;
2470
2471 return ret;
2472 }
2473
onOrientationEvent(uint32_t orientation,uint32_t tilt)2474 void OMXCameraAdapter::onOrientationEvent(uint32_t orientation, uint32_t tilt)
2475 {
2476 LOG_FUNCTION_NAME;
2477
2478 static const unsigned int DEGREES_TILT_IGNORE = 45;
2479 int device_orientation = 0;
2480 int mount_orientation = 0;
2481 const char *facing_direction = NULL;
2482
2483 // if tilt angle is greater than DEGREES_TILT_IGNORE
2484 // we are going to ignore the orientation returned from
2485 // sensor. the orientation returned from sensor is not
2486 // reliable. Value of DEGREES_TILT_IGNORE may need adjusting
2487 if (tilt > DEGREES_TILT_IGNORE) {
2488 return;
2489 }
2490
2491 if (mCapabilities) {
2492 if (mCapabilities->get(CameraProperties::ORIENTATION_INDEX)) {
2493 mount_orientation = atoi(mCapabilities->get(CameraProperties::ORIENTATION_INDEX));
2494 }
2495 facing_direction = mCapabilities->get(CameraProperties::FACING_INDEX);
2496 }
2497
2498 // calculate device orientation relative to the sensor orientation
2499 // front camera display is mirrored...needs to be accounted for when orientation
2500 // is 90 or 270...since this will result in a flip on orientation otherwise
2501 if (facing_direction && !strcmp(facing_direction, TICameraParameters::FACING_FRONT) &&
2502 (orientation == 90 || orientation == 270)) {
2503 device_orientation = (orientation - mount_orientation + 360) % 360;
2504 } else { // back-facing camera
2505 device_orientation = (orientation + mount_orientation) % 360;
2506 }
2507
2508 if (device_orientation != mDeviceOrientation) {
2509 mDeviceOrientation = device_orientation;
2510
2511 mFaceDetectionLock.lock();
2512 if (mFaceDetectionRunning) {
2513 // restart face detection with new rotation
2514 setFaceDetection(true, mDeviceOrientation);
2515 }
2516 mFaceDetectionLock.unlock();
2517 }
2518 CAMHAL_LOGVB("orientation = %d tilt = %d device_orientation = %d", orientation, tilt, mDeviceOrientation);
2519
2520 LOG_FUNCTION_NAME_EXIT;
2521 }
2522
2523 /* Application callback Functions */
2524 /*========================================================*/
2525 /* @ fn SampleTest_EventHandler :: Application callback */
2526 /*========================================================*/
OMXCameraAdapterEventHandler(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_PTR pAppData,OMX_IN OMX_EVENTTYPE eEvent,OMX_IN OMX_U32 nData1,OMX_IN OMX_U32 nData2,OMX_IN OMX_PTR pEventData)2527 OMX_ERRORTYPE OMXCameraAdapterEventHandler(OMX_IN OMX_HANDLETYPE hComponent,
2528 OMX_IN OMX_PTR pAppData,
2529 OMX_IN OMX_EVENTTYPE eEvent,
2530 OMX_IN OMX_U32 nData1,
2531 OMX_IN OMX_U32 nData2,
2532 OMX_IN OMX_PTR pEventData)
2533 {
2534 LOG_FUNCTION_NAME;
2535
2536 CAMHAL_LOGDB("Event %d", eEvent);
2537
2538 OMX_ERRORTYPE ret = OMX_ErrorNone;
2539 OMXCameraAdapter *oca = (OMXCameraAdapter*)pAppData;
2540 ret = oca->OMXCameraAdapterEventHandler(hComponent, eEvent, nData1, nData2, pEventData);
2541
2542 LOG_FUNCTION_NAME_EXIT;
2543 return ret;
2544 }
2545
2546 /* Application callback Functions */
2547 /*========================================================*/
2548 /* @ fn SampleTest_EventHandler :: Application callback */
2549 /*========================================================*/
OMXCameraAdapterEventHandler(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_EVENTTYPE eEvent,OMX_IN OMX_U32 nData1,OMX_IN OMX_U32 nData2,OMX_IN OMX_PTR pEventData)2550 OMX_ERRORTYPE OMXCameraAdapter::OMXCameraAdapterEventHandler(OMX_IN OMX_HANDLETYPE hComponent,
2551 OMX_IN OMX_EVENTTYPE eEvent,
2552 OMX_IN OMX_U32 nData1,
2553 OMX_IN OMX_U32 nData2,
2554 OMX_IN OMX_PTR pEventData)
2555 {
2556
2557 LOG_FUNCTION_NAME;
2558
2559 OMX_ERRORTYPE eError = OMX_ErrorNone;
2560 CAMHAL_LOGDB("+OMX_Event %x, %d %d", eEvent, (int)nData1, (int)nData2);
2561
2562 switch (eEvent) {
2563 case OMX_EventCmdComplete:
2564 CAMHAL_LOGDB("+OMX_EventCmdComplete %d %d", (int)nData1, (int)nData2);
2565
2566 if (OMX_CommandStateSet == nData1) {
2567 mCameraAdapterParameters.mState = (OMX_STATETYPE) nData2;
2568
2569 } else if (OMX_CommandFlush == nData1) {
2570 CAMHAL_LOGDB("OMX_CommandFlush received for port %d", (int)nData2);
2571
2572 } else if (OMX_CommandPortDisable == nData1) {
2573 CAMHAL_LOGDB("OMX_CommandPortDisable received for port %d", (int)nData2);
2574
2575 } else if (OMX_CommandPortEnable == nData1) {
2576 CAMHAL_LOGDB("OMX_CommandPortEnable received for port %d", (int)nData2);
2577
2578 } else if (OMX_CommandMarkBuffer == nData1) {
2579 ///This is not used currently
2580 }
2581
2582 CAMHAL_LOGDA("-OMX_EventCmdComplete");
2583 break;
2584
2585 case OMX_EventIndexSettingChanged:
2586 CAMHAL_LOGDB("OMX_EventIndexSettingChanged event received data1 0x%x, data2 0x%x",
2587 ( unsigned int ) nData1, ( unsigned int ) nData2);
2588 break;
2589
2590 case OMX_EventError:
2591 CAMHAL_LOGDB("OMX interface failed to execute OMX command %d", (int)nData1);
2592 CAMHAL_LOGDA("See OMX_INDEXTYPE for reference");
2593 if ( NULL != mErrorNotifier && ( ( OMX_U32 ) OMX_ErrorHardware == nData1 ) && mComponentState != OMX_StateInvalid)
2594 {
2595 CAMHAL_LOGEA("***Got Fatal Error Notification***\n");
2596 mComponentState = OMX_StateInvalid;
2597 /*
2598 Remove any unhandled events and
2599 unblock any waiting semaphores
2600 */
2601 if ( !mEventSignalQ.isEmpty() )
2602 {
2603 for (unsigned int i = 0 ; i < mEventSignalQ.size(); i++ )
2604 {
2605 CAMHAL_LOGEB("***Removing %d EVENTS***** \n", mEventSignalQ.size());
2606 //remove from queue and free msg
2607 TIUTILS::Message *msg = mEventSignalQ.itemAt(i);
2608 if ( NULL != msg )
2609 {
2610 Semaphore *sem = (Semaphore*) msg->arg3;
2611 mEventSignalQ.removeAt(i);
2612 if ( sem )
2613 {
2614 sem->Signal();
2615 }
2616 free(msg);
2617 }
2618 }
2619 }
2620 ///Report Error to App
2621 mErrorNotifier->errorNotify(CAMERA_ERROR_FATAL);
2622 }
2623 break;
2624
2625 case OMX_EventMark:
2626 break;
2627
2628 case OMX_EventPortSettingsChanged:
2629 break;
2630
2631 case OMX_EventBufferFlag:
2632 break;
2633
2634 case OMX_EventResourcesAcquired:
2635 break;
2636
2637 case OMX_EventComponentResumed:
2638 break;
2639
2640 case OMX_EventDynamicResourcesAvailable:
2641 break;
2642
2643 case OMX_EventPortFormatDetected:
2644 break;
2645
2646 default:
2647 break;
2648 }
2649
2650 ///Signal to the thread(s) waiting that the event has occured
2651 SignalEvent(hComponent, eEvent, nData1, nData2, pEventData);
2652
2653 LOG_FUNCTION_NAME_EXIT;
2654 return eError;
2655
2656 EXIT:
2657
2658 CAMHAL_LOGEB("Exiting function %s because of eError=%x", __FUNCTION__, eError);
2659 LOG_FUNCTION_NAME_EXIT;
2660 return eError;
2661 }
2662
SignalEvent(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_EVENTTYPE eEvent,OMX_IN OMX_U32 nData1,OMX_IN OMX_U32 nData2,OMX_IN OMX_PTR pEventData)2663 OMX_ERRORTYPE OMXCameraAdapter::SignalEvent(OMX_IN OMX_HANDLETYPE hComponent,
2664 OMX_IN OMX_EVENTTYPE eEvent,
2665 OMX_IN OMX_U32 nData1,
2666 OMX_IN OMX_U32 nData2,
2667 OMX_IN OMX_PTR pEventData)
2668 {
2669 Mutex::Autolock lock(mEventLock);
2670 TIUTILS::Message *msg;
2671
2672 LOG_FUNCTION_NAME;
2673
2674 if ( !mEventSignalQ.isEmpty() )
2675 {
2676 CAMHAL_LOGDA("Event queue not empty");
2677
2678 for ( unsigned int i = 0 ; i < mEventSignalQ.size() ; i++ )
2679 {
2680 msg = mEventSignalQ.itemAt(i);
2681 if ( NULL != msg )
2682 {
2683 if( ( msg->command != 0 || msg->command == ( unsigned int ) ( eEvent ) )
2684 && ( !msg->arg1 || ( OMX_U32 ) msg->arg1 == nData1 )
2685 && ( !msg->arg2 || ( OMX_U32 ) msg->arg2 == nData2 )
2686 && msg->arg3)
2687 {
2688 Semaphore *sem = (Semaphore*) msg->arg3;
2689 CAMHAL_LOGDA("Event matched, signalling sem");
2690 mEventSignalQ.removeAt(i);
2691 //Signal the semaphore provided
2692 sem->Signal();
2693 free(msg);
2694 break;
2695 }
2696 }
2697 }
2698 }
2699 else
2700 {
2701 CAMHAL_LOGEA("Event queue empty!!!");
2702 }
2703
2704 LOG_FUNCTION_NAME_EXIT;
2705
2706 return OMX_ErrorNone;
2707 }
2708
RemoveEvent(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_EVENTTYPE eEvent,OMX_IN OMX_U32 nData1,OMX_IN OMX_U32 nData2,OMX_IN OMX_PTR pEventData)2709 OMX_ERRORTYPE OMXCameraAdapter::RemoveEvent(OMX_IN OMX_HANDLETYPE hComponent,
2710 OMX_IN OMX_EVENTTYPE eEvent,
2711 OMX_IN OMX_U32 nData1,
2712 OMX_IN OMX_U32 nData2,
2713 OMX_IN OMX_PTR pEventData)
2714 {
2715 Mutex::Autolock lock(mEventLock);
2716 TIUTILS::Message *msg;
2717 LOG_FUNCTION_NAME;
2718
2719 if ( !mEventSignalQ.isEmpty() )
2720 {
2721 CAMHAL_LOGDA("Event queue not empty");
2722
2723 for ( unsigned int i = 0 ; i < mEventSignalQ.size() ; i++ )
2724 {
2725 msg = mEventSignalQ.itemAt(i);
2726 if ( NULL != msg )
2727 {
2728 if( ( msg->command != 0 || msg->command == ( unsigned int ) ( eEvent ) )
2729 && ( !msg->arg1 || ( OMX_U32 ) msg->arg1 == nData1 )
2730 && ( !msg->arg2 || ( OMX_U32 ) msg->arg2 == nData2 )
2731 && msg->arg3)
2732 {
2733 Semaphore *sem = (Semaphore*) msg->arg3;
2734 CAMHAL_LOGDA("Event matched, signalling sem");
2735 mEventSignalQ.removeAt(i);
2736 free(msg);
2737 break;
2738 }
2739 }
2740 }
2741 }
2742 else
2743 {
2744 CAMHAL_LOGEA("Event queue empty!!!");
2745 }
2746 LOG_FUNCTION_NAME_EXIT;
2747
2748 return OMX_ErrorNone;
2749 }
2750
2751
RegisterForEvent(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_EVENTTYPE eEvent,OMX_IN OMX_U32 nData1,OMX_IN OMX_U32 nData2,OMX_IN Semaphore & semaphore)2752 status_t OMXCameraAdapter::RegisterForEvent(OMX_IN OMX_HANDLETYPE hComponent,
2753 OMX_IN OMX_EVENTTYPE eEvent,
2754 OMX_IN OMX_U32 nData1,
2755 OMX_IN OMX_U32 nData2,
2756 OMX_IN Semaphore &semaphore)
2757 {
2758 status_t ret = NO_ERROR;
2759 ssize_t res;
2760 Mutex::Autolock lock(mEventLock);
2761
2762 LOG_FUNCTION_NAME;
2763 TIUTILS::Message * msg = ( struct TIUTILS::Message * ) malloc(sizeof(struct TIUTILS::Message));
2764 if ( NULL != msg )
2765 {
2766 msg->command = ( unsigned int ) eEvent;
2767 msg->arg1 = ( void * ) nData1;
2768 msg->arg2 = ( void * ) nData2;
2769 msg->arg3 = ( void * ) &semaphore;
2770 msg->arg4 = ( void * ) hComponent;
2771 res = mEventSignalQ.add(msg);
2772 if ( NO_MEMORY == res )
2773 {
2774 CAMHAL_LOGEA("No ressources for inserting OMX events");
2775 free(msg);
2776 ret = -ENOMEM;
2777 }
2778 }
2779
2780 LOG_FUNCTION_NAME_EXIT;
2781
2782 return ret;
2783 }
2784
2785 /*========================================================*/
2786 /* @ fn SampleTest_EmptyBufferDone :: Application callback*/
2787 /*========================================================*/
OMXCameraAdapterEmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_PTR pAppData,OMX_IN OMX_BUFFERHEADERTYPE * pBuffHeader)2788 OMX_ERRORTYPE OMXCameraAdapterEmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
2789 OMX_IN OMX_PTR pAppData,
2790 OMX_IN OMX_BUFFERHEADERTYPE* pBuffHeader)
2791 {
2792 LOG_FUNCTION_NAME;
2793
2794 OMX_ERRORTYPE eError = OMX_ErrorNone;
2795
2796 OMXCameraAdapter *oca = (OMXCameraAdapter*)pAppData;
2797 eError = oca->OMXCameraAdapterEmptyBufferDone(hComponent, pBuffHeader);
2798
2799 LOG_FUNCTION_NAME_EXIT;
2800 return eError;
2801 }
2802
2803
2804 /*========================================================*/
2805 /* @ fn SampleTest_EmptyBufferDone :: Application callback*/
2806 /*========================================================*/
OMXCameraAdapterEmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_BUFFERHEADERTYPE * pBuffHeader)2807 OMX_ERRORTYPE OMXCameraAdapter::OMXCameraAdapterEmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
2808 OMX_IN OMX_BUFFERHEADERTYPE* pBuffHeader)
2809 {
2810
2811 LOG_FUNCTION_NAME;
2812
2813 LOG_FUNCTION_NAME_EXIT;
2814
2815 return OMX_ErrorNone;
2816 }
2817
debugShowFPS()2818 static void debugShowFPS()
2819 {
2820 static int mFrameCount = 0;
2821 static int mLastFrameCount = 0;
2822 static nsecs_t mLastFpsTime = 0;
2823 static float mFps = 0;
2824 mFrameCount++;
2825 if (!(mFrameCount & 0x1F)) {
2826 nsecs_t now = systemTime();
2827 nsecs_t diff = now - mLastFpsTime;
2828 mFps = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
2829 mLastFpsTime = now;
2830 mLastFrameCount = mFrameCount;
2831 LOGD("Camera %d Frames, %f FPS", mFrameCount, mFps);
2832 }
2833 // XXX: mFPS has the value we want
2834 }
2835
2836 /*========================================================*/
2837 /* @ fn SampleTest_FillBufferDone :: Application callback*/
2838 /*========================================================*/
OMXCameraAdapterFillBufferDone(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_PTR pAppData,OMX_IN OMX_BUFFERHEADERTYPE * pBuffHeader)2839 OMX_ERRORTYPE OMXCameraAdapterFillBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
2840 OMX_IN OMX_PTR pAppData,
2841 OMX_IN OMX_BUFFERHEADERTYPE* pBuffHeader)
2842 {
2843 TIUTILS::Message msg;
2844 OMX_ERRORTYPE eError = OMX_ErrorNone;
2845
2846 if (UNLIKELY(mDebugFps)) {
2847 debugShowFPS();
2848 }
2849
2850 OMXCameraAdapter *adapter = ( OMXCameraAdapter * ) pAppData;
2851 if ( NULL != adapter )
2852 {
2853 msg.command = OMXCameraAdapter::OMXCallbackHandler::CAMERA_FILL_BUFFER_DONE;
2854 msg.arg1 = ( void * ) hComponent;
2855 msg.arg2 = ( void * ) pBuffHeader;
2856 adapter->mOMXCallbackHandler->put(&msg);
2857 }
2858
2859 return eError;
2860 }
2861
2862 /*========================================================*/
2863 /* @ fn SampleTest_FillBufferDone :: Application callback*/
2864 /*========================================================*/
OMXCameraAdapterFillBufferDone(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_BUFFERHEADERTYPE * pBuffHeader)2865 OMX_ERRORTYPE OMXCameraAdapter::OMXCameraAdapterFillBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
2866 OMX_IN OMX_BUFFERHEADERTYPE* pBuffHeader)
2867 {
2868
2869 status_t stat = NO_ERROR;
2870 status_t res1, res2;
2871 OMXCameraPortParameters *pPortParam;
2872 OMX_ERRORTYPE eError = OMX_ErrorNone;
2873 CameraFrame::FrameType typeOfFrame = CameraFrame::ALL_FRAMES;
2874 unsigned int refCount = 0;
2875 BaseCameraAdapter::AdapterState state, nextState;
2876 BaseCameraAdapter::getState(state);
2877 BaseCameraAdapter::getNextState(nextState);
2878 sp<CameraFDResult> fdResult = NULL;
2879 unsigned int mask = 0xFFFF;
2880 CameraFrame cameraFrame;
2881
2882 res1 = res2 = NO_ERROR;
2883 pPortParam = &(mCameraAdapterParameters.mCameraPortParams[pBuffHeader->nOutputPortIndex]);
2884
2885 if ( !pBuffHeader || !pBuffHeader->pBuffer ) {
2886 CAMHAL_LOGEA("NULL Buffer from OMX");
2887 return OMX_ErrorNone;
2888 }
2889
2890 if (pBuffHeader->nOutputPortIndex == OMX_CAMERA_PORT_VIDEO_OUT_PREVIEW)
2891 {
2892
2893 if ( ( PREVIEW_ACTIVE & state ) != PREVIEW_ACTIVE )
2894 {
2895 return OMX_ErrorNone;
2896 }
2897
2898 recalculateFPS();
2899
2900 {
2901 Mutex::Autolock lock(mFaceDetectionLock);
2902 if ( mFaceDetectionRunning && !mFaceDetectionPaused ) {
2903 detectFaces(pBuffHeader, fdResult, pPortParam->mWidth, pPortParam->mHeight);
2904 if ( NULL != fdResult.get() ) {
2905 notifyFaceSubscribers(fdResult);
2906 fdResult.clear();
2907 }
2908 }
2909 }
2910
2911 if ( (nextState & CAPTURE_ACTIVE) )
2912 {
2913 mPending3Asettings |= SetFocus;
2914 }
2915
2916 ///Prepare the frames to be sent - initialize CameraFrame object and reference count
2917 if( mWaitingForSnapshot && (mCapturedFrames > 0) )
2918 {
2919 typeOfFrame = CameraFrame::SNAPSHOT_FRAME;
2920 mask = (unsigned int)CameraFrame::SNAPSHOT_FRAME;
2921 }
2922 else
2923 {
2924 typeOfFrame = CameraFrame::PREVIEW_FRAME_SYNC;
2925 mask = (unsigned int)CameraFrame::PREVIEW_FRAME_SYNC;
2926 }
2927
2928 if (mRecording)
2929 {
2930 mask |= (unsigned int)CameraFrame::VIDEO_FRAME_SYNC;
2931 mFramesWithEncoder++;
2932 }
2933
2934 //LOGV("FBD pBuffer = 0x%x", pBuffHeader->pBuffer);
2935
2936 if( mWaitingForSnapshot )
2937 {
2938 mSnapshotCount++;
2939
2940 if ( (mSnapshotCount == 1) &&
2941 ((HIGH_SPEED == mCapMode) || (VIDEO_MODE == mCapMode)) )
2942 {
2943 notifyShutterSubscribers();
2944 }
2945 }
2946
2947 stat = sendCallBacks(cameraFrame, pBuffHeader, mask, pPortParam);
2948 mFramesWithDisplay++;
2949
2950 mFramesWithDucati--;
2951
2952 #ifdef DEBUG_LOG
2953 if(mBuffersWithDucati.indexOfKey((int)pBuffHeader->pBuffer)<0)
2954 {
2955 LOGE("Buffer was never with Ducati!! 0x%x", pBuffHeader->pBuffer);
2956 for(int i=0;i<mBuffersWithDucati.size();i++) LOGE("0x%x", mBuffersWithDucati.keyAt(i));
2957 }
2958 mBuffersWithDucati.removeItem((int)pBuffHeader->pBuffer);
2959 #endif
2960
2961 if(mDebugFcs)
2962 CAMHAL_LOGEB("C[%d] D[%d] E[%d]", mFramesWithDucati, mFramesWithDisplay, mFramesWithEncoder);
2963
2964 stat |= advanceZoom();
2965
2966 // On the fly update to 3A settings not working
2967 // Do not update 3A here if we are in the middle of a capture
2968 // or in the middle of transitioning to it
2969 if( mPending3Asettings && ((nextState & CAPTURE_ACTIVE) == 0))
2970 {
2971 apply3Asettings(mParameters3A);
2972 }
2973 }
2974 else if( pBuffHeader->nOutputPortIndex == OMX_CAMERA_PORT_VIDEO_OUT_MEASUREMENT )
2975 {
2976 typeOfFrame = CameraFrame::FRAME_DATA_SYNC;
2977 mask = (unsigned int)CameraFrame::FRAME_DATA_SYNC;
2978
2979 stat = sendCallBacks(cameraFrame, pBuffHeader, mask, pPortParam);
2980 }
2981 else if( pBuffHeader->nOutputPortIndex == OMX_CAMERA_PORT_IMAGE_OUT_IMAGE )
2982 {
2983 OMX_COLOR_FORMATTYPE pixFormat;
2984 const char *valstr = NULL;
2985
2986 pixFormat = mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex].mColorFormat;
2987 valstr = mParams.getPictureFormat();
2988
2989 if ( OMX_COLOR_FormatUnused == pixFormat )
2990 {
2991 typeOfFrame = CameraFrame::IMAGE_FRAME;
2992 mask = (unsigned int) CameraFrame::IMAGE_FRAME;
2993 }
2994 else if ( pixFormat == OMX_COLOR_FormatCbYCrY &&
2995 ((valstr && !strcmp(valstr, CameraParameters::PIXEL_FORMAT_JPEG)) ||
2996 !valstr) )
2997 {
2998 // signals to callbacks that this needs to be coverted to jpeg
2999 // before returning to framework
3000 typeOfFrame = CameraFrame::IMAGE_FRAME;
3001 mask = (unsigned int) CameraFrame::IMAGE_FRAME;
3002 cameraFrame.mQuirks |= CameraFrame::ENCODE_RAW_YUV422I_TO_JPEG;
3003
3004 // populate exif data and pass to subscribers via quirk
3005 // subscriber is in charge of freeing exif data
3006 ExifElementsTable* exif = new ExifElementsTable();
3007 setupEXIF_libjpeg(exif);
3008 cameraFrame.mQuirks |= CameraFrame::HAS_EXIF_DATA;
3009 cameraFrame.mCookie2 = (void*) exif;
3010 }
3011 else
3012 {
3013 typeOfFrame = CameraFrame::RAW_FRAME;
3014 mask = (unsigned int) CameraFrame::RAW_FRAME;
3015 }
3016
3017 pPortParam->mImageType = typeOfFrame;
3018
3019 if((mCapturedFrames>0) && !mCaptureSignalled)
3020 {
3021 mCaptureSignalled = true;
3022 mCaptureSem.Signal();
3023 }
3024
3025 if( ( CAPTURE_ACTIVE & state ) != CAPTURE_ACTIVE )
3026 {
3027 goto EXIT;
3028 }
3029
3030 {
3031 Mutex::Autolock lock(mBracketingLock);
3032 if ( mBracketingEnabled )
3033 {
3034 doBracketing(pBuffHeader, typeOfFrame);
3035 return eError;
3036 }
3037 }
3038
3039 if ( 1 > mCapturedFrames )
3040 {
3041 goto EXIT;
3042 }
3043
3044 CAMHAL_LOGDB("Captured Frames: %d", mCapturedFrames);
3045
3046 mCapturedFrames--;
3047
3048 stat = sendCallBacks(cameraFrame, pBuffHeader, mask, pPortParam);
3049
3050 }
3051 else
3052 {
3053 CAMHAL_LOGEA("Frame received for non-(preview/capture/measure) port. This is yet to be supported");
3054 goto EXIT;
3055 }
3056
3057 if ( NO_ERROR != stat )
3058 {
3059 CAMHAL_LOGDB("sendFrameToSubscribers error: %d", stat);
3060 returnFrame(pBuffHeader->pBuffer, typeOfFrame);
3061 }
3062
3063 return eError;
3064
3065 EXIT:
3066
3067 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, stat, eError);
3068
3069 if ( NO_ERROR != stat )
3070 {
3071 if ( NULL != mErrorNotifier )
3072 {
3073 mErrorNotifier->errorNotify(CAMERA_ERROR_UNKNOWN);
3074 }
3075 }
3076
3077 return eError;
3078 }
3079
recalculateFPS()3080 status_t OMXCameraAdapter::recalculateFPS()
3081 {
3082 float currentFPS;
3083
3084 {
3085 Mutex::Autolock lock(mFrameCountMutex);
3086 mFrameCount++;
3087 if (mFrameCount == 1) {
3088 mFirstFrameCondition.broadcast();
3089 }
3090 }
3091
3092 if ( ( mFrameCount % FPS_PERIOD ) == 0 )
3093 {
3094 nsecs_t now = systemTime();
3095 nsecs_t diff = now - mLastFPSTime;
3096 currentFPS = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
3097 mLastFPSTime = now;
3098 mLastFrameCount = mFrameCount;
3099
3100 if ( 1 == mIter )
3101 {
3102 mFPS = currentFPS;
3103 }
3104 else
3105 {
3106 //cumulative moving average
3107 mFPS = mLastFPS + (currentFPS - mLastFPS)/mIter;
3108 }
3109
3110 mLastFPS = mFPS;
3111 mIter++;
3112 }
3113
3114 return NO_ERROR;
3115 }
3116
sendFrame(CameraFrame & frame)3117 status_t OMXCameraAdapter::sendFrame(CameraFrame &frame)
3118 {
3119 status_t ret = NO_ERROR;
3120
3121 LOG_FUNCTION_NAME;
3122
3123
3124 if ( NO_ERROR == ret )
3125 {
3126 ret = sendFrameToSubscribers(&frame);
3127 }
3128
3129 LOG_FUNCTION_NAME_EXIT;
3130
3131 return ret;
3132 }
3133
sendCallBacks(CameraFrame frame,OMX_IN OMX_BUFFERHEADERTYPE * pBuffHeader,unsigned int mask,OMXCameraPortParameters * port)3134 status_t OMXCameraAdapter::sendCallBacks(CameraFrame frame, OMX_IN OMX_BUFFERHEADERTYPE *pBuffHeader, unsigned int mask, OMXCameraPortParameters *port)
3135 {
3136 status_t ret = NO_ERROR;
3137
3138 LOG_FUNCTION_NAME;
3139
3140 if ( NULL == port)
3141 {
3142 CAMHAL_LOGEA("Invalid portParam");
3143 return -EINVAL;
3144 }
3145
3146 if ( NULL == pBuffHeader )
3147 {
3148 CAMHAL_LOGEA("Invalid Buffer header");
3149 return -EINVAL;
3150 }
3151
3152 Mutex::Autolock lock(mSubscriberLock);
3153
3154 //frame.mFrameType = typeOfFrame;
3155 frame.mFrameMask = mask;
3156 frame.mBuffer = pBuffHeader->pBuffer;
3157 frame.mLength = pBuffHeader->nFilledLen;
3158 frame.mAlignment = port->mStride;
3159 frame.mOffset = pBuffHeader->nOffset;
3160 frame.mWidth = port->mWidth;
3161 frame.mHeight = port->mHeight;
3162 frame.mYuv[0] = NULL;
3163 frame.mYuv[1] = NULL;
3164
3165 if ( onlyOnce && mRecording )
3166 {
3167 mTimeSourceDelta = (pBuffHeader->nTimeStamp * 1000) - systemTime(SYSTEM_TIME_MONOTONIC);
3168 onlyOnce = false;
3169 }
3170
3171 frame.mTimestamp = (pBuffHeader->nTimeStamp * 1000) - mTimeSourceDelta;
3172
3173 ret = setInitFrameRefCount(frame.mBuffer, mask);
3174
3175 if (ret != NO_ERROR) {
3176 CAMHAL_LOGDB("Error in setInitFrameRefCount %d", ret);
3177 } else {
3178 ret = sendFrameToSubscribers(&frame);
3179 }
3180
3181 CAMHAL_LOGVB("B 0x%x T %llu", frame.mBuffer, pBuffHeader->nTimeStamp);
3182
3183 LOG_FUNCTION_NAME_EXIT;
3184
3185 return ret;
3186 }
3187
initCameraFrame(CameraFrame & frame,OMX_IN OMX_BUFFERHEADERTYPE * pBuffHeader,int typeOfFrame,OMXCameraPortParameters * port)3188 status_t OMXCameraAdapter::initCameraFrame( CameraFrame &frame,
3189 OMX_IN OMX_BUFFERHEADERTYPE *pBuffHeader,
3190 int typeOfFrame,
3191 OMXCameraPortParameters *port)
3192 {
3193 status_t ret = NO_ERROR;
3194
3195 LOG_FUNCTION_NAME;
3196
3197 if ( NULL == port)
3198 {
3199 CAMHAL_LOGEA("Invalid portParam");
3200 return -EINVAL;
3201 }
3202
3203 if ( NULL == pBuffHeader )
3204 {
3205 CAMHAL_LOGEA("Invalid Buffer header");
3206 return -EINVAL;
3207 }
3208
3209 frame.mFrameType = typeOfFrame;
3210 frame.mBuffer = pBuffHeader->pBuffer;
3211 frame.mLength = pBuffHeader->nFilledLen;
3212 frame.mAlignment = port->mStride;
3213 frame.mOffset = pBuffHeader->nOffset;
3214 frame.mWidth = port->mWidth;
3215 frame.mHeight = port->mHeight;
3216
3217 // Timestamp in pBuffHeader->nTimeStamp is derived on DUCATI side, which is
3218 // is not same time value as derived using systemTime. It would be ideal to use
3219 // exactly same time source across Android and Ducati, which is limited by
3220 // system now. So, workaround for now is to find the time offset between the two
3221 // time sources and compensate the difference, along with the latency involved
3222 // in camera buffer reaching CameraHal. Also, Do timeset offset calculation only
3223 // when recording is in progress, when nTimestamp will be populated by Camera
3224 if ( onlyOnce && mRecording )
3225 {
3226 mTimeSourceDelta = (pBuffHeader->nTimeStamp * 1000) - systemTime(SYSTEM_TIME_MONOTONIC);
3227 mTimeSourceDelta += kCameraBufferLatencyNs;
3228 onlyOnce = false;
3229 }
3230
3231 // Calculating the new video timestamp based on offset from ducati source.
3232 frame.mTimestamp = (pBuffHeader->nTimeStamp * 1000) - mTimeSourceDelta;
3233
3234 LOG_FUNCTION_NAME_EXIT;
3235
3236 return ret;
3237 }
3238
Handler()3239 bool OMXCameraAdapter::CommandHandler::Handler()
3240 {
3241 TIUTILS::Message msg;
3242 volatile int forever = 1;
3243 status_t stat;
3244 ErrorNotifier *errorNotify = NULL;
3245
3246 LOG_FUNCTION_NAME;
3247
3248 while ( forever )
3249 {
3250 stat = NO_ERROR;
3251 CAMHAL_LOGDA("Handler: waiting for messsage...");
3252 TIUTILS::MessageQueue::waitForMsg(&mCommandMsgQ, NULL, NULL, -1);
3253 mCommandMsgQ.get(&msg);
3254 CAMHAL_LOGDB("msg.command = %d", msg.command);
3255 switch ( msg.command ) {
3256 case CommandHandler::CAMERA_START_IMAGE_CAPTURE:
3257 {
3258 stat = mCameraAdapter->startImageCapture();
3259 break;
3260 }
3261 case CommandHandler::CAMERA_PERFORM_AUTOFOCUS:
3262 {
3263 stat = mCameraAdapter->doAutoFocus();
3264 break;
3265 }
3266 case CommandHandler::COMMAND_EXIT:
3267 {
3268 CAMHAL_LOGEA("Exiting command handler");
3269 forever = 0;
3270 break;
3271 }
3272 case CommandHandler::CAMERA_SWITCH_TO_EXECUTING:
3273 {
3274 stat = mCameraAdapter->doSwitchToExecuting();
3275 break;
3276 }
3277 }
3278
3279 if ( NO_ERROR != stat )
3280 {
3281 errorNotify = ( ErrorNotifier * ) msg.arg1;
3282 if ( NULL != errorNotify )
3283 {
3284 errorNotify->errorNotify(CAMERA_ERROR_HARD);
3285 }
3286 }
3287 }
3288
3289 LOG_FUNCTION_NAME_EXIT;
3290
3291 return false;
3292 }
3293
Handler()3294 bool OMXCameraAdapter::OMXCallbackHandler::Handler()
3295 {
3296 TIUTILS::Message msg;
3297 volatile int forever = 1;
3298 status_t ret = NO_ERROR;
3299
3300 LOG_FUNCTION_NAME;
3301
3302 while(forever){
3303 TIUTILS::MessageQueue::waitForMsg(&mCommandMsgQ, NULL, NULL, -1);
3304 mCommandMsgQ.get(&msg);
3305 switch ( msg.command ) {
3306 case OMXCallbackHandler::CAMERA_FILL_BUFFER_DONE:
3307 {
3308 ret = mCameraAdapter->OMXCameraAdapterFillBufferDone(( OMX_HANDLETYPE ) msg.arg1,
3309 ( OMX_BUFFERHEADERTYPE *) msg.arg2);
3310 break;
3311 }
3312 case CommandHandler::COMMAND_EXIT:
3313 {
3314 CAMHAL_LOGEA("Exiting OMX callback handler");
3315 forever = 0;
3316 break;
3317 }
3318 }
3319 }
3320
3321 LOG_FUNCTION_NAME_EXIT;
3322 return false;
3323 }
3324
OMXCameraAdapter(size_t sensor_index)3325 OMXCameraAdapter::OMXCameraAdapter(size_t sensor_index): mComponentState (OMX_StateLoaded)
3326 {
3327 LOG_FUNCTION_NAME;
3328
3329 mSensorIndex = sensor_index;
3330 mPictureRotation = 0;
3331 // Initial values
3332 mTimeSourceDelta = 0;
3333 onlyOnce = true;
3334
3335 mDoAFSem.Create(0);
3336 mInitSem.Create(0);
3337 mFlushSem.Create(0);
3338 mUsePreviewDataSem.Create(0);
3339 mUsePreviewSem.Create(0);
3340 mUseCaptureSem.Create(0);
3341 mStartPreviewSem.Create(0);
3342 mStopPreviewSem.Create(0);
3343 mStartCaptureSem.Create(0);
3344 mStopCaptureSem.Create(0);
3345 mSwitchToLoadedSem.Create(0);
3346 mCaptureSem.Create(0);
3347
3348 mSwitchToExecSem.Create(0);
3349
3350 mCameraAdapterParameters.mHandleComp = 0;
3351
3352 mUserSetExpLock = OMX_FALSE;
3353 mUserSetWbLock = OMX_FALSE;
3354
3355 mFramesWithDucati = 0;
3356 mFramesWithDisplay = 0;
3357 mFramesWithEncoder = 0;
3358
3359 LOG_FUNCTION_NAME_EXIT;
3360 }
3361
~OMXCameraAdapter()3362 OMXCameraAdapter::~OMXCameraAdapter()
3363 {
3364 LOG_FUNCTION_NAME;
3365
3366 Mutex::Autolock lock(gAdapterLock);
3367
3368 //Return to OMX Loaded state
3369 switchToLoaded();
3370
3371 ///De-init the OMX
3372 if( (mComponentState==OMX_StateLoaded) || (mComponentState==OMX_StateInvalid))
3373 {
3374 ///Free the handle for the Camera component
3375 if(mCameraAdapterParameters.mHandleComp)
3376 {
3377 OMX_FreeHandle(mCameraAdapterParameters.mHandleComp);
3378 mCameraAdapterParameters.mHandleComp = NULL;
3379 }
3380
3381 OMX_Deinit();
3382 }
3383
3384
3385 //Remove any unhandled events
3386 if ( !mEventSignalQ.isEmpty() )
3387 {
3388 for (unsigned int i = 0 ; i < mEventSignalQ.size() ; i++ )
3389 {
3390 TIUTILS::Message *msg = mEventSignalQ.itemAt(i);
3391 //remove from queue and free msg
3392 if ( NULL != msg )
3393 {
3394 Semaphore *sem = (Semaphore*) msg->arg3;
3395 mEventSignalQ.removeAt(i);
3396 sem->Signal();
3397 free(msg);
3398
3399 }
3400 }
3401 }
3402
3403 //Exit and free ref to command handling thread
3404 if ( NULL != mCommandHandler.get() )
3405 {
3406 TIUTILS::Message msg;
3407 msg.command = CommandHandler::COMMAND_EXIT;
3408 msg.arg1 = mErrorNotifier;
3409 mCommandHandler->put(&msg);
3410 mCommandHandler->requestExitAndWait();
3411 mCommandHandler.clear();
3412 }
3413
3414 //Exit and free ref to callback handling thread
3415 if ( NULL != mOMXCallbackHandler.get() )
3416 {
3417 TIUTILS::Message msg;
3418 msg.command = OMXCallbackHandler::COMMAND_EXIT;
3419 mOMXCallbackHandler->put(&msg);
3420 mOMXCallbackHandler->requestExitAndWait();
3421 mOMXCallbackHandler.clear();
3422 }
3423
3424 LOG_FUNCTION_NAME_EXIT;
3425 }
3426
CameraAdapter_Factory(size_t sensor_index)3427 extern "C" CameraAdapter* CameraAdapter_Factory(size_t sensor_index)
3428 {
3429 CameraAdapter *adapter = NULL;
3430 Mutex::Autolock lock(gAdapterLock);
3431
3432 LOG_FUNCTION_NAME;
3433
3434 adapter = new OMXCameraAdapter(sensor_index);
3435 if ( adapter ) {
3436 CAMHAL_LOGDB("New OMX Camera adapter instance created for sensor %d",sensor_index);
3437 } else {
3438 CAMHAL_LOGEA("Camera adapter create failed!");
3439 }
3440
3441 LOG_FUNCTION_NAME_EXIT;
3442
3443 return adapter;
3444 }
3445
OMXCameraGetHandle(OMX_HANDLETYPE * handle,OMX_PTR pAppData)3446 OMX_ERRORTYPE OMXCameraAdapter::OMXCameraGetHandle(OMX_HANDLETYPE *handle, OMX_PTR pAppData )
3447 {
3448 OMX_ERRORTYPE eError = OMX_ErrorUndefined;
3449
3450 int retries = 5;
3451 while(eError!=OMX_ErrorNone && --retries>=0) {
3452
3453 // Setup key parameters to send to Ducati during init
3454 OMX_CALLBACKTYPE oCallbacks;
3455
3456 // Initialize the callback handles
3457 oCallbacks.EventHandler = android::OMXCameraAdapterEventHandler;
3458 oCallbacks.EmptyBufferDone = android::OMXCameraAdapterEmptyBufferDone;
3459 oCallbacks.FillBufferDone = android::OMXCameraAdapterFillBufferDone;
3460
3461 // Get Handle
3462 eError = OMX_GetHandle(handle, (OMX_STRING)"OMX.TI.DUCATI1.VIDEO.CAMERA", pAppData, &oCallbacks);
3463 if (eError != OMX_ErrorNone) {
3464 CAMHAL_LOGEB("OMX_GetHandle -0x%x", eError);
3465 //Sleep for 100 mS
3466 usleep(100000);
3467 } else {
3468 break;
3469 }
3470 }
3471
3472 return eError;
3473 }
3474
CameraAdapter_Capabilities(CameraProperties::Properties * properties_array,const unsigned int starting_camera,const unsigned int max_camera)3475 extern "C" int CameraAdapter_Capabilities(CameraProperties::Properties* properties_array,
3476 const unsigned int starting_camera,
3477 const unsigned int max_camera) {
3478 int num_cameras_supported = 0;
3479 CameraProperties::Properties* properties = NULL;
3480 OMX_ERRORTYPE eError = OMX_ErrorNone;
3481 OMX_HANDLETYPE handle = NULL;
3482 OMX_TI_CAPTYPE caps;
3483
3484 LOG_FUNCTION_NAME;
3485
3486 Mutex::Autolock lock(gAdapterLock);
3487
3488 if (!properties_array) {
3489 CAMHAL_LOGEB("invalid param: properties = 0x%p", properties_array);
3490 LOG_FUNCTION_NAME_EXIT;
3491 return -EINVAL;
3492 }
3493
3494 eError = OMX_Init();
3495 if (eError != OMX_ErrorNone) {
3496 CAMHAL_LOGEB("Error OMX_Init -0x%x", eError);
3497 return eError;
3498 }
3499
3500 eError = OMXCameraAdapter::OMXCameraGetHandle(&handle);
3501 if (eError != OMX_ErrorNone) {
3502 CAMHAL_LOGEB("OMX_GetHandle -0x%x", eError);
3503 goto EXIT;
3504 }
3505
3506 // Continue selecting sensor and then querying OMX Camera for it's capabilities
3507 // When sensor select returns an error, we know to break and stop
3508 while (eError == OMX_ErrorNone &&
3509 (starting_camera + num_cameras_supported) < max_camera) {
3510 // sensor select
3511 OMX_CONFIG_SENSORSELECTTYPE sensorSelect;
3512 OMX_INIT_STRUCT_PTR (&sensorSelect, OMX_CONFIG_SENSORSELECTTYPE);
3513 sensorSelect.eSensor = (OMX_SENSORSELECT) num_cameras_supported;
3514 eError = OMX_SetConfig(handle, ( OMX_INDEXTYPE ) OMX_TI_IndexConfigSensorSelect, &sensorSelect);
3515
3516 if ( OMX_ErrorNone != eError ) {
3517 break;
3518 }
3519
3520 // get and fill capabilities
3521 properties = properties_array + starting_camera + num_cameras_supported;
3522 OMXCameraAdapter::getCaps(properties, handle);
3523
3524 // need to fill facing information
3525 // assume that only sensor 0 is back facing
3526 if (num_cameras_supported == 0) {
3527 properties->set(CameraProperties::FACING_INDEX, TICameraParameters::FACING_BACK);
3528 } else {
3529 properties->set(CameraProperties::FACING_INDEX, TICameraParameters::FACING_FRONT);
3530 }
3531
3532 num_cameras_supported++;
3533 }
3534
3535 EXIT:
3536 // clean up
3537 if(handle) {
3538 OMX_FreeHandle(handle);
3539 handle=NULL;
3540 }
3541 OMX_Deinit();
3542
3543 LOG_FUNCTION_NAME_EXIT;
3544
3545 return num_cameras_supported;
3546 }
3547
3548 };
3549
3550
3551 /*--------------------Camera Adapter Class ENDS here-----------------------------*/
3552
3553