1 /*
2 ** Copyright (c) 2011-2012,2015 The Linux Foundation. All rights reserved.
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 /*#error uncomment this for compiler test!*/
18 #define ALOG_NIDEBUG 0
19
20 #define LOG_TAG "QCameraHWI"
21 #include <utils/Log.h>
22 #include <utils/threads.h>
23 #include <cutils/properties.h>
24 #include <fcntl.h>
25 #include <sys/mman.h>
26 #include <string.h>
27 #include <dlfcn.h>
28
29 #include "QCameraHAL.h"
30 #include "QCameraHWI.h"
31
32 /* QCameraHardwareInterface class implementation goes here*/
33 /* following code implement the contol logic of this class*/
34
35 namespace android {
HAL_event_cb(mm_camera_event_t * evt,void * user_data)36 static void HAL_event_cb(mm_camera_event_t *evt, void *user_data)
37 {
38 QCameraHardwareInterface *obj = (QCameraHardwareInterface *)user_data;
39 if (obj) {
40 obj->processEvent(evt);
41 } else {
42 ALOGE("%s: NULL user_data", __func__);
43 }
44 }
45
createRecord()46 int32_t QCameraHardwareInterface::createRecord()
47 {
48 int32_t ret = MM_CAMERA_OK;
49 ALOGV("%s : BEGIN",__func__);
50
51 /*
52 * Creating Instance of record stream.
53 */
54 ALOGV("Mymode Record = %d",myMode);
55 mStreamRecord = QCameraStream_record::createInstance(mCameraId,
56 myMode);
57
58 if (!mStreamRecord) {
59 ALOGE("%s: error - can't creat record stream!", __func__);
60 return BAD_VALUE;
61 }
62
63 /* Store HAL object in record stream Object */
64 mStreamRecord->setHALCameraControl(this);
65
66 /*Init Channel */
67 ret = mStreamRecord->init();
68 if (MM_CAMERA_OK != ret){
69 ALOGE("%s: error - can't init Record channel!", __func__);
70 return BAD_VALUE;
71 }
72 ALOGV("%s : END",__func__);
73 return ret;
74 }
75
createSnapshot()76 int32_t QCameraHardwareInterface::createSnapshot()
77 {
78 int32_t ret = MM_CAMERA_OK;
79 ALOGV("%s : BEGIN",__func__);
80
81 /*
82 * Creating Instance of Snapshot stream.
83 */
84 ALOGV("Mymode Snap = %d",myMode);
85 mStreamSnap = QCameraStream_Snapshot::createInstance(mCameraId,
86 myMode);
87 if (!mStreamSnap) {
88 ALOGE("%s: error - can't creat snapshot stream!", __func__);
89 return BAD_VALUE;
90 }
91
92 /* Store HAL object in Snapshot stream Object */
93 mStreamSnap->setHALCameraControl(this);
94
95 /*Init Channel */
96 ret = mStreamSnap->init();
97 if (MM_CAMERA_OK != ret){
98 ALOGE("%s: error - can't init Snapshot channel!", __func__);
99 return BAD_VALUE;
100 }
101 ALOGV("%s : END",__func__);
102 return ret;
103 }
104
createPreview()105 int32_t QCameraHardwareInterface::createPreview()
106 {
107 int32_t ret = MM_CAMERA_OK;
108 ALOGV("%s : BEGIN",__func__);
109
110 ALOGV("Mymode Preview = %d",myMode);
111 mStreamDisplay = QCameraStream_preview::createInstance(mCameraId,
112 myMode);
113 if (!mStreamDisplay) {
114 ALOGE("%s: error - can't creat preview stream!", __func__);
115 return BAD_VALUE;
116 }
117
118 mStreamDisplay->setHALCameraControl(this);
119
120 /*now init all the buffers and send to steam object*/
121 ret = mStreamDisplay->init();
122 if (MM_CAMERA_OK != ret){
123 ALOGE("%s: error - can't init Preview channel!", __func__);
124 return BAD_VALUE;
125 }
126 ALOGV("%s : END",__func__);
127 return ret;
128 }
129
130 /* constructor */
131 QCameraHardwareInterface::
QCameraHardwareInterface(int cameraId,int mode)132 QCameraHardwareInterface(int cameraId, int mode)
133 : mCameraId(cameraId),
134 mParameters(),
135 mMsgEnabled(0),
136 mNotifyCb(0),
137 mDataCb(0),
138 mDataCbTimestamp(0),
139 mCallbackCookie(0),
140 //mPreviewHeap(0),
141 mStreamDisplay (NULL), mStreamRecord(NULL), mStreamSnap(NULL),
142 mFps(0),
143 mDebugFps(0),
144 mMaxZoom(0),
145 mCurrentZoom(0),
146 mSupportedPictureSizesCount(15),
147 mDumpFrmCnt(0), mDumpSkipCnt(0),
148 mPictureSizeCount(15),
149 mPreviewSizeCount(13),
150 mVideoSizeCount(0),
151 mAutoFocusRunning(false),
152 mNeedToUnlockCaf(false),
153 mHasAutoFocusSupport(false),
154 mInitialized(false),
155 mIs3DModeOn(0),
156 mSmoothZoomRunning(false),
157 mParamStringInitialized(false),
158 mFaceDetectOn(0),
159 mDisEnabled(0),
160 mZoomSupported(false),
161 mFullLiveshotEnabled(false),
162 mRecordingHint(false),
163 mAppRecordingHint(false),
164 mStatsOn(0), mCurrentHisto(-1), mSendData(false), mStatHeap(NULL),
165 mZslLookBackMode(0),
166 mZslLookBackValue(0),
167 mZslEmptyQueueFlag(false),
168 mPictureSizes(NULL),
169 mVideoSizes(NULL),
170 mCameraState(CAMERA_STATE_UNINITED),
171 mPostPreviewHeap(NULL),
172 mHdrMode(HDR_BRACKETING_OFF),
173 mStreamLiveSnap(NULL),
174 mExifTableNumEntries(0),
175 mDenoiseValue(0),
176 mSnapshotFormat(0),
177 mStartRecording(0),
178 mZslInterval(1),
179 mBrightness(0),
180 mContrast(0),
181 mEffects(0),
182 mBestShotMode(0),
183 mHJR(0),
184 mSkinToneEnhancement(0),
185 mRotation(0),
186 mFocusMode(AF_MODE_MAX),
187 mPreviewFormat(CAMERA_YUV_420_NV21),
188 mRestartPreview(false),
189 mReleasedRecordingFrame(false),
190 mStateLiveshot(false),
191 isCameraOpen(false),
192 mPauseFramedispatch(false),
193 mSnapJpegCbRunning(false),
194 mSnapCbDisabled(false)
195 {
196 ALOGV("QCameraHardwareInterface: E");
197 int32_t result = MM_CAMERA_E_GENERAL;
198 char value[PROPERTY_VALUE_MAX];
199
200 pthread_mutex_init(&mAsyncCmdMutex, NULL);
201 pthread_cond_init(&mAsyncCmdWait, NULL);
202 mFlashCond = false;
203
204 property_get("persist.debug.sf.showfps", value, "0");
205 mDebugFps = atoi(value);
206 mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED;
207 mPreviewWindow = NULL;
208 property_get("camera.hal.fps", value, "0");
209 mFps = atoi(value);
210
211 ALOGV("Init mPreviewState = %d", mPreviewState);
212
213 property_get("persist.camera.hal.multitouchaf", value, "0");
214 mMultiTouch = atoi(value);
215
216 property_get("persist.camera.full.liveshot", value, "0");
217 mFullLiveshotEnabled = atoi(value);
218
219 property_get("persist.camera.hal.dis", value, "0");
220 mDisEnabled = atoi(value);
221
222 /* Open camera stack! */
223 result=cam_ops_open(mCameraId, MM_CAMERA_OP_MODE_NOTUSED);
224 if (result == MM_CAMERA_OK) {
225 int i;
226 mm_camera_event_type_t evt;
227 for (i = 0; i < MM_CAMERA_EVT_TYPE_MAX; i++) {
228 evt = (mm_camera_event_type_t) i;
229 if (cam_evt_is_event_supported(mCameraId, evt)){
230 cam_evt_register_event_notify(mCameraId,
231 HAL_event_cb, (void *)this, evt);
232 }
233 }
234 }
235 ALOGV("Cam open returned %d",result);
236 if(MM_CAMERA_OK != result) {
237 ALOGE("startCamera: cam_ops_open failed: id = %d", mCameraId);
238 return;
239 }
240
241 loadTables();
242 /* Setup Picture Size and Preview size tables */
243 setPictureSizeTable();
244 ALOGV("%s: Picture table size: %d", __func__, mPictureSizeCount);
245 ALOGV("%s: Picture table: ", __func__);
246 for(unsigned int i=0; i < mPictureSizeCount;i++) {
247 ALOGV(" %d %d", mPictureSizes[i].width, mPictureSizes[i].height);
248 }
249
250 setPreviewSizeTable();
251 ALOGV("%s: Preview table size: %d", __func__, mPreviewSizeCount);
252 ALOGV("%s: Preview table: ", __func__);
253 for(unsigned int i=0; i < mPreviewSizeCount;i++) {
254 ALOGV(" %d %d", mPreviewSizes[i].width, mPreviewSizes[i].height);
255 }
256
257 setVideoSizeTable();
258 ALOGV("%s: Video table size: %d", __func__, mVideoSizeCount);
259 ALOGV("%s: Video table: ", __func__);
260 for(unsigned int i=0; i < mVideoSizeCount;i++) {
261 ALOGV(" %d %d", mVideoSizes[i].width, mVideoSizes[i].height);
262 }
263
264 isCameraOpen = true;
265 /* set my mode - update myMode member variable due to difference in
266 enum definition between upper and lower layer*/
267 setMyMode(mode);
268 initDefaultParameters();
269
270 //Create Stream Objects
271 //Preview
272 result = createPreview();
273 if(result != MM_CAMERA_OK) {
274 ALOGE("%s X: Failed to create Preview Object",__func__);
275 return;
276 }
277
278 //Record
279 result = createRecord();
280 if(result != MM_CAMERA_OK) {
281 ALOGE("%s X: Failed to create Record Object",__func__);
282 return;
283 }
284
285 //Snapshot
286 result = createSnapshot();
287 if(result != MM_CAMERA_OK) {
288 ALOGE("%s X: Failed to create Record Object",__func__);
289 return;
290 }
291 mCameraState = CAMERA_STATE_READY;
292 libdnr = dlopen("libmorpho_noise_reduction.so", RTLD_NOW);
293 if (libdnr) {
294 ALOGV("Open MM camera DL libmorpho_noise_reduction loaded at %p & %p ", libdnr);
295 *(void **)&LINK_morpho_DNR_ProcessFrame = dlsym(libdnr, "LINK_mm_camera_morpho_noise_reduction");
296 }
297 else
298 ALOGE("failed to open libmorpho_noise_reduction");
299
300 ALOGV("QCameraHardwareInterface: X");
301 }
302
~QCameraHardwareInterface()303 QCameraHardwareInterface::~QCameraHardwareInterface()
304 {
305 ALOGV("~QCameraHardwareInterface: E");
306 int result;
307
308 switch(mPreviewState) {
309 case QCAMERA_HAL_PREVIEW_STOPPED:
310 break;
311 case QCAMERA_HAL_PREVIEW_START:
312 break;
313 case QCAMERA_HAL_PREVIEW_STARTED:
314 stopPreview();
315 break;
316 case QCAMERA_HAL_RECORDING_STARTED:
317 stopRecordingInternal();
318 stopPreview();
319 break;
320 case QCAMERA_HAL_TAKE_PICTURE:
321 cancelPictureInternal();
322 break;
323 default:
324 break;
325 }
326 mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED;
327
328 if (isCameraOpen) {
329 freePictureTable();
330 freeVideoSizeTable();
331 if(mStatHeap != NULL) {
332 mStatHeap.clear( );
333 mStatHeap = NULL;
334 }
335 }
336 /*First stop the polling threads*/
337 ALOGI("%s First stop the polling threads before deleting instances", __func__);
338 cam_ops_stop(mCameraId);
339 /* Join the threads, complete operations and then delete
340 the instances. */
341 if(mStreamDisplay){
342 QCameraStream_preview::deleteInstance (mStreamDisplay);
343 mStreamDisplay = NULL;
344 }
345 if(mStreamRecord) {
346 QCameraStream_record::deleteInstance (mStreamRecord);
347 mStreamRecord = NULL;
348 }
349 if(mStreamSnap) {
350 QCameraStream_Snapshot::deleteInstance (mStreamSnap);
351 mStreamSnap = NULL;
352 }
353 if (libdnr != NULL) {
354 dlclose(libdnr);
355 libdnr = NULL;
356 ALOGV("closed libmorpho_noise_reduction.so");
357 }
358
359 if (mStreamLiveSnap){
360 QCameraStream_Snapshot::deleteInstance (mStreamLiveSnap);
361 mStreamLiveSnap = NULL;
362 }
363
364 /* Now close the camera after deleting all the instances */
365 cam_ops_close(mCameraId);
366 pthread_mutex_destroy(&mAsyncCmdMutex);
367 pthread_cond_destroy(&mAsyncCmdWait);
368 isCameraOpen = false;
369
370 ALOGV("~QCameraHardwareInterface: X");
371 }
372
isCameraReady()373 bool QCameraHardwareInterface::isCameraReady()
374 {
375 ALOGV("isCameraReady mCameraState %d", mCameraState);
376 return (mCameraState == CAMERA_STATE_READY);
377 }
378
release()379 void QCameraHardwareInterface::release()
380 {
381 ALOGV("release: E");
382 Mutex::Autolock l(&mLock);
383
384 switch(mPreviewState) {
385 case QCAMERA_HAL_PREVIEW_STOPPED:
386 break;
387 case QCAMERA_HAL_PREVIEW_START:
388 break;
389 case QCAMERA_HAL_PREVIEW_STARTED:
390 stopPreviewInternal();
391 break;
392 case QCAMERA_HAL_RECORDING_STARTED:
393 stopRecordingInternal();
394 stopPreviewInternal();
395 break;
396 case QCAMERA_HAL_TAKE_PICTURE:
397 cancelPictureInternal();
398 break;
399 default:
400 break;
401 }
402 #if 0
403 if (isRecordingRunning()) {
404 stopRecordingInternal();
405 ALOGI("release: stopRecordingInternal done.");
406 }
407 if (isPreviewRunning()) {
408 stopPreview(); //stopPreviewInternal();
409 ALOGI("release: stopPreviewInternal done.");
410 }
411 if (isSnapshotRunning()) {
412 cancelPictureInternal();
413 ALOGI("release: cancelPictureInternal done.");
414 }
415 if (mCameraState == CAMERA_STATE_ERROR) {
416 //TBD: If Error occurs then tear down
417 ALOGI("release: Tear down.");
418 }
419 #endif
420 mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED;
421 ALOGV("release: X");
422 }
423
setCallbacks(camera_notify_callback notify_cb,camera_data_callback data_cb,camera_data_timestamp_callback data_cb_timestamp,camera_request_memory get_memory,void * user)424 void QCameraHardwareInterface::setCallbacks(
425 camera_notify_callback notify_cb,
426 camera_data_callback data_cb,
427 camera_data_timestamp_callback data_cb_timestamp,
428 camera_request_memory get_memory,
429 void *user)
430 {
431 ALOGV("setCallbacks: E");
432 Mutex::Autolock lock(mLock);
433 mNotifyCb = notify_cb;
434 mDataCb = data_cb;
435 mDataCbTimestamp = data_cb_timestamp;
436 mGetMemory = get_memory;
437 mCallbackCookie = user;
438 ALOGV("setCallbacks: X");
439 }
440
enableMsgType(int32_t msgType)441 void QCameraHardwareInterface::enableMsgType(int32_t msgType)
442 {
443 ALOGV("enableMsgType: E, msgType =0x%x", msgType);
444 Mutex::Autolock lock(mLock);
445 mMsgEnabled |= msgType;
446 ALOGV("enableMsgType: X, msgType =0x%x, mMsgEnabled=0x%x", msgType, mMsgEnabled);
447 }
448
disableMsgType(int32_t msgType)449 void QCameraHardwareInterface::disableMsgType(int32_t msgType)
450 {
451 ALOGV("disableMsgType: E");
452 Mutex::Autolock lock(mLock);
453 mMsgEnabled &= ~msgType;
454 ALOGV("disableMsgType: X, msgType =0x%x, mMsgEnabled=0x%x", msgType, mMsgEnabled);
455 }
456
msgTypeEnabled(int32_t msgType)457 int QCameraHardwareInterface::msgTypeEnabled(int32_t msgType)
458 {
459 ALOGV("msgTypeEnabled: E");
460 Mutex::Autolock lock(mLock);
461 return (mMsgEnabled & msgType);
462 ALOGV("msgTypeEnabled: X");
463 }
464 #if 0
465 status_t QCameraHardwareInterface::dump(int fd, const Vector<String16>& args) const
466 {
467 ALOGI("dump: E");
468 const size_t SIZE = 256;
469 char buffer[SIZE];
470 String8 result;
471 AutoMutex lock(&mLock);
472 write(fd, result.string(), result.size());
473 ALOGI("dump: E");
474 return NO_ERROR;
475 }
476 #endif
477
dump(int fd)478 int QCameraHardwareInterface::dump(int fd)
479 {
480 ALOGE("%s: not supported yet", __func__);
481 return -1;
482 }
483
sendCommand(int32_t command,int32_t arg1,int32_t arg2)484 status_t QCameraHardwareInterface::sendCommand(int32_t command, int32_t arg1,
485 int32_t arg2)
486 {
487 ALOGV("sendCommand: E");
488 status_t rc = NO_ERROR;
489 Mutex::Autolock l(&mLock);
490
491 switch (command) {
492 case CAMERA_CMD_START_FACE_DETECTION:
493 if(supportsFaceDetection() == false){
494 ALOGE("Face detection support is not available");
495 return NO_ERROR;
496 }
497 setFaceDetection("on");
498 return runFaceDetection();
499 case CAMERA_CMD_STOP_FACE_DETECTION:
500 if(supportsFaceDetection() == false){
501 ALOGE("Face detection support is not available");
502 return NO_ERROR;
503 }
504 setFaceDetection("off");
505 return runFaceDetection();
506
507 #if 0
508 case CAMERA_CMD_HISTOGRAM_ON:
509 ALOGE("histogram set to on");
510 rc = setHistogram(1);
511 break;
512 case CAMERA_CMD_HISTOGRAM_OFF:
513 ALOGE("histogram set to off");
514 rc = setHistogram(0);
515 break;
516 case CAMERA_CMD_HISTOGRAM_SEND_DATA:
517 ALOGE("histogram send data");
518 mSendData = true;
519 rc = NO_ERROR;
520 break;
521 case CAMERA_CMD_SEND_META_DATA:
522 mMetaDataWaitLock.lock();
523 if(mFaceDetectOn == true) {
524 mSendMetaData = true;
525 }
526 mMetaDataWaitLock.unlock();
527 return NO_ERROR;
528 #endif
529 #if 0 /* To Do: will enable it later */
530 case CAMERA_CMD_START_SMOOTH_ZOOM :
531 ALOGV("HAL sendcmd start smooth zoom %d %d", arg1 , arg2);
532 /*TO DO: get MaxZoom from parameter*/
533 int MaxZoom = 100;
534
535 switch(mCameraState ) {
536 case CAMERA_STATE_PREVIEW:
537 case CAMERA_STATE_RECORD_CMD_SENT:
538 case CAMERA_STATE_RECORD:
539 mTargetSmoothZoom = arg1;
540 mCurrentZoom = mParameters.getInt("zoom");
541 mSmoothZoomStep = (mCurrentZoom > mTargetSmoothZoom)? -1: 1;
542 if(mCurrentZoom == mTargetSmoothZoom) {
543 ALOGV("Smoothzoom target zoom value is same as "
544 "current zoom value, return...");
545 mNotifyCallback(CAMERA_MSG_ZOOM,
546 mCurrentZoom, 1, mCallbackCookie);
547 } else if(mCurrentZoom < 0 || mCurrentZoom > MaxZoom ||
548 mTargetSmoothZoom < 0 || mTargetSmoothZoom > MaxZoom) {
549 ALOGE(" ERROR : beyond supported zoom values, break..");
550 mNotifyCallback(CAMERA_MSG_ZOOM,
551 mCurrentZoom, 0, mCallbackCookie);
552 } else {
553 mSmoothZoomRunning = true;
554 mCurrentZoom += mSmoothZoomStep;
555 if ((mSmoothZoomStep < 0 && mCurrentZoom < mTargetSmoothZoom)||
556 (mSmoothZoomStep > 0 && mCurrentZoom > mTargetSmoothZoom )) {
557 mCurrentZoom = mTargetSmoothZoom;
558 }
559 mParameters.set("zoom", mCurrentZoom);
560 setZoom(mParameters);
561 }
562 break;
563 default:
564 ALOGV(" No preview, no smoothzoom ");
565 break;
566 }
567 rc = NO_ERROR;
568 break;
569
570 case CAMERA_CMD_STOP_SMOOTH_ZOOM:
571 if(mSmoothZoomRunning) {
572 mSmoothZoomRunning = false;
573 /*To Do: send cmd to stop zooming*/
574 }
575 ALOGV("HAL sendcmd stop smooth zoom");
576 rc = NO_ERROR;
577 break;
578 #endif
579 default:
580 break;
581 }
582 ALOGV("sendCommand: X");
583 return rc;
584 }
585
setMyMode(int mode)586 void QCameraHardwareInterface::setMyMode(int mode)
587 {
588 ALOGV("setMyMode: E");
589 //if (mode & CAMERA_SUPPORT_MODE_3D) {
590 // myMode = CAMERA_MODE_3D;
591 //}else {
592 /* default mode is 2D */
593 myMode = CAMERA_MODE_2D;
594 //}
595
596 //if (mode & CAMERA_SUPPORT_MODE_ZSL) {
597 // myMode = (camera_mode_t)(myMode |CAMERA_ZSL_MODE);
598 //}else {
599 myMode = (camera_mode_t) (myMode | CAMERA_NONZSL_MODE);
600 //}
601 ALOGV("setMyMode: Set mode to %d (passed mode: %d)", myMode, mode);
602 ALOGV("setMyMode: X");
603 }
604 /* static factory function */
createInstance(int cameraId,int mode)605 QCameraHardwareInterface *QCameraHardwareInterface::createInstance(int cameraId, int mode)
606 {
607 ALOGV("createInstance: E");
608 QCameraHardwareInterface *cam = new QCameraHardwareInterface(cameraId, mode);
609 if (cam ) {
610 if (cam->mCameraState != CAMERA_STATE_READY) {
611 ALOGE("createInstance: Failed");
612 delete cam;
613 cam = NULL;
614 }
615 }
616
617 if (cam) {
618 //sp<CameraHardwareInterface> hardware(cam);
619 ALOGV("createInstance: X");
620 return cam;
621 } else {
622 return NULL;
623 }
624 }
625 /* external plug in function */
626 extern "C" void *
QCameraHAL_openCameraHardware(int cameraId,int mode)627 QCameraHAL_openCameraHardware(int cameraId, int mode)
628 {
629 ALOGV("QCameraHAL_openCameraHardware: E");
630 return (void *) QCameraHardwareInterface::createInstance(cameraId, mode);
631 }
632
isPreviewRunning()633 bool QCameraHardwareInterface::isPreviewRunning() {
634 ALOGV("isPreviewRunning: E");
635 bool ret = false;
636 ALOGV("isPreviewRunning: camera state:%d", mCameraState);
637
638 if((mCameraState == CAMERA_STATE_PREVIEW) ||
639 (mCameraState == CAMERA_STATE_PREVIEW_START_CMD_SENT) ||
640 (mCameraState == CAMERA_STATE_RECORD) ||
641 (mCameraState == CAMERA_STATE_RECORD_START_CMD_SENT) ||
642 (mCameraState == CAMERA_STATE_ZSL) ||
643 (mCameraState == CAMERA_STATE_ZSL_START_CMD_SENT)){
644 return true;
645 }
646 ALOGV("isPreviewRunning: X");
647 return ret;
648 }
649
isRecordingRunning()650 bool QCameraHardwareInterface::isRecordingRunning() {
651 ALOGV("isRecordingRunning: E");
652 bool ret = false;
653 if(QCAMERA_HAL_RECORDING_STARTED == mPreviewState)
654 ret = true;
655 //if((mCameraState == CAMERA_STATE_RECORD) ||
656 // (mCameraState == CAMERA_STATE_RECORD_START_CMD_SENT)) {
657 // return true;
658 //}
659 ALOGV("isRecordingRunning: X");
660 return ret;
661 }
662
isSnapshotRunning()663 bool QCameraHardwareInterface::isSnapshotRunning() {
664 ALOGV("isSnapshotRunning: E");
665 bool ret = false;
666 //if((mCameraState == CAMERA_STATE_SNAP_CMD_ACKED) ||
667 // (mCameraState == CAMERA_STATE_SNAP_START_CMD_SENT)) {
668 // return true;
669 //}
670 switch(mPreviewState) {
671 case QCAMERA_HAL_PREVIEW_STOPPED:
672 case QCAMERA_HAL_PREVIEW_START:
673 case QCAMERA_HAL_PREVIEW_STARTED:
674 case QCAMERA_HAL_RECORDING_STARTED:
675 default:
676 break;
677 case QCAMERA_HAL_TAKE_PICTURE:
678 ret = true;
679 break;
680 }
681 ALOGV("isSnapshotRunning: X");
682 return ret;
683 }
684
isZSLMode()685 bool QCameraHardwareInterface::isZSLMode() {
686 return (myMode & CAMERA_ZSL_MODE);
687 }
688
getHDRMode()689 int QCameraHardwareInterface::getHDRMode() {
690 return mHdrMode;
691 }
692
debugShowPreviewFPS() const693 void QCameraHardwareInterface::debugShowPreviewFPS() const
694 {
695 static int mFrameCount;
696 static int mLastFrameCount = 0;
697 static nsecs_t mLastFpsTime = 0;
698 static float mFps = 0;
699 mFrameCount++;
700 nsecs_t now = systemTime();
701 nsecs_t diff = now - mLastFpsTime;
702 if (diff > ms2ns(250)) {
703 mFps = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
704 ALOGV("Preview Frames Per Second: %.4f", mFps);
705 mLastFpsTime = now;
706 mLastFrameCount = mFrameCount;
707 }
708 }
709
710 void QCameraHardwareInterface::
processPreviewChannelEvent(mm_camera_ch_event_type_t channelEvent,app_notify_cb_t * app_cb)711 processPreviewChannelEvent(mm_camera_ch_event_type_t channelEvent, app_notify_cb_t *app_cb) {
712 ALOGV("processPreviewChannelEvent: E");
713 switch(channelEvent) {
714 case MM_CAMERA_CH_EVT_STREAMING_ON:
715 mCameraState =
716 isZSLMode() ? CAMERA_STATE_ZSL : CAMERA_STATE_PREVIEW;
717 break;
718 case MM_CAMERA_CH_EVT_STREAMING_OFF:
719 mCameraState = CAMERA_STATE_READY;
720 break;
721 case MM_CAMERA_CH_EVT_DATA_DELIVERY_DONE:
722 break;
723 default:
724 break;
725 }
726 ALOGV("processPreviewChannelEvent: X");
727 return;
728 }
729
processRecordChannelEvent(mm_camera_ch_event_type_t channelEvent,app_notify_cb_t * app_cb)730 void QCameraHardwareInterface::processRecordChannelEvent(
731 mm_camera_ch_event_type_t channelEvent, app_notify_cb_t *app_cb) {
732 ALOGV("processRecordChannelEvent: E");
733 switch(channelEvent) {
734 case MM_CAMERA_CH_EVT_STREAMING_ON:
735 mCameraState = CAMERA_STATE_RECORD;
736 break;
737 case MM_CAMERA_CH_EVT_STREAMING_OFF:
738 mCameraState = CAMERA_STATE_PREVIEW;
739 break;
740 case MM_CAMERA_CH_EVT_DATA_DELIVERY_DONE:
741 break;
742 default:
743 break;
744 }
745 ALOGV("processRecordChannelEvent: X");
746 return;
747 }
748
749 void QCameraHardwareInterface::
processSnapshotChannelEvent(mm_camera_ch_event_type_t channelEvent,app_notify_cb_t * app_cb)750 processSnapshotChannelEvent(mm_camera_ch_event_type_t channelEvent, app_notify_cb_t *app_cb) {
751 ALOGV("processSnapshotChannelEvent: E evt=%d state=%d", channelEvent,
752 mCameraState);
753 switch(channelEvent) {
754 case MM_CAMERA_CH_EVT_STREAMING_ON:
755 if (!mStateLiveshot) {
756 mCameraState =
757 isZSLMode() ? CAMERA_STATE_ZSL : CAMERA_STATE_SNAP_CMD_ACKED;
758 }
759 break;
760 case MM_CAMERA_CH_EVT_STREAMING_OFF:
761 if (!mStateLiveshot) {
762 mCameraState = CAMERA_STATE_READY;
763 }
764 break;
765 case MM_CAMERA_CH_EVT_DATA_DELIVERY_DONE:
766 break;
767 case MM_CAMERA_CH_EVT_DATA_REQUEST_MORE:
768 if (isZSLMode()) {
769 /* ZSL Mode: In ZSL Burst Mode, users may request for number of
770 snapshots larger than internal size of ZSL queue. So we'll need
771 process the remaining frames as they become available.
772 In such case, we'll get this event */
773 if(NULL != mStreamSnap)
774 mStreamSnap->takePictureZSL();
775 }
776 break;
777 default:
778 break;
779 }
780 ALOGV("processSnapshotChannelEvent: X");
781 return;
782 }
783
processChannelEvent(mm_camera_ch_event_t * event,app_notify_cb_t * app_cb)784 void QCameraHardwareInterface::processChannelEvent(
785 mm_camera_ch_event_t *event, app_notify_cb_t *app_cb)
786 {
787 ALOGV("processChannelEvent: E");
788 Mutex::Autolock lock(mLock);
789 switch(event->ch) {
790 case MM_CAMERA_CH_PREVIEW:
791 processPreviewChannelEvent(event->evt, app_cb);
792 break;
793 case MM_CAMERA_CH_VIDEO:
794 processRecordChannelEvent(event->evt, app_cb);
795 break;
796 case MM_CAMERA_CH_SNAPSHOT:
797 processSnapshotChannelEvent(event->evt, app_cb);
798 break;
799 default:
800 break;
801 }
802 ALOGV("processChannelEvent: X");
803 return;
804 }
805
processCtrlEvent(mm_camera_ctrl_event_t * event,app_notify_cb_t * app_cb)806 void QCameraHardwareInterface::processCtrlEvent(mm_camera_ctrl_event_t *event, app_notify_cb_t *app_cb)
807 {
808 ALOGV("processCtrlEvent: %d, E",event->evt);
809 Mutex::Autolock lock(mLock);
810 switch(event->evt)
811 {
812 case MM_CAMERA_CTRL_EVT_ZOOM_DONE:
813 zoomEvent(&event->status, app_cb);
814 break;
815 case MM_CAMERA_CTRL_EVT_AUTO_FOCUS_DONE:
816 autoFocusEvent(&event->status, app_cb);
817 break;
818 case MM_CAMERA_CTRL_EVT_AUTO_FOCUS_MOVE:
819 autoFocusMoveEvent(&event->status, app_cb);
820 break;
821 case MM_CAMERA_CTRL_EVT_PREP_SNAPSHOT:
822 break;
823 case MM_CAMERA_CTRL_EVT_WDN_DONE:
824 wdenoiseEvent(event->status, (void *)(event->cookie));
825 break;
826 case MM_CAMERA_CTRL_EVT_HDR_DONE:
827 hdrEvent(event->status, (void *)(event->cookie));
828 break;
829 case MM_CAMERA_CTRL_EVT_ERROR:
830 app_cb->notifyCb = mNotifyCb;
831 app_cb->argm_notify.msg_type = CAMERA_MSG_ERROR;
832 app_cb->argm_notify.ext1 = CAMERA_ERROR_UNKNOWN;
833 app_cb->argm_notify.cookie = mCallbackCookie;
834 break;
835 case MM_CAMERA_CTRL_EVT_SNAPSHOT_CONFIG_DONE:
836 ALOGV("%s: MM_CAMERA_CTRL_EVT_SNAPSHOT_CONFIG_DONE", __func__);
837 app_cb->notifyCb = mNotifyCb;
838 app_cb->argm_notify.msg_type = CAMERA_MSG_SHUTTER;
839 app_cb->argm_notify.ext1 = 0;
840 app_cb->argm_notify.ext2 = true;
841 app_cb->argm_notify.cookie = mCallbackCookie;
842 mShutterSoundPlayed = true;
843 default:
844 break;
845 }
846 ALOGV("processCtrlEvent: X");
847 return;
848 }
849
processStatsEvent(mm_camera_stats_event_t * event,app_notify_cb_t * app_cb)850 void QCameraHardwareInterface::processStatsEvent(
851 mm_camera_stats_event_t *event, app_notify_cb_t *app_cb)
852 {
853 ALOGV("processStatsEvent: E");
854 if (!isPreviewRunning( )) {
855 ALOGE("preview is not running");
856 return;
857 }
858
859 switch (event->event_id) {
860
861 case MM_CAMERA_STATS_EVT_HISTO:
862 {
863 #if 0
864 ALOGE("HAL process Histo: mMsgEnabled=0x%x, mStatsOn=%d, mSendData=%d, mDataCb=%p ",
865 (mMsgEnabled & CAMERA_MSG_STATS_DATA), mStatsOn, mSendData, mDataCb);
866 int msgEnabled = mMsgEnabled;
867 /*get stats buffer based on index*/
868 camera_preview_histogram_info* hist_info =
869 (camera_preview_histogram_info*) mHistServer.camera_memory[event->e.stats_histo.index]->data;
870
871 if(mStatsOn == QCAMERA_PARM_ENABLE && mSendData &&
872 mDataCb && (msgEnabled & CAMERA_MSG_STATS_DATA) ) {
873 uint32_t *dest;
874 mSendData = false;
875 mCurrentHisto = (mCurrentHisto + 1) % 3;
876 // The first element of the array will contain the maximum hist value provided by driver.
877 *(uint32_t *)((unsigned int)(mStatsMapped[mCurrentHisto]->data)) = hist_info->max_value;
878 memcpy((uint32_t *)((unsigned int)mStatsMapped[mCurrentHisto]->data + sizeof(int32_t)),
879 (uint32_t *)hist_info->buffer,(sizeof(int32_t) * 256));
880
881 app_cb->dataCb = mDataCb;
882 app_cb->argm_data_cb.msg_type = CAMERA_MSG_STATS_DATA;
883 app_cb->argm_data_cb.data = mStatsMapped[mCurrentHisto];
884 app_cb->argm_data_cb.index = 0;
885 app_cb->argm_data_cb.metadata = NULL;
886 app_cb->argm_data_cb.cookie = mCallbackCookie;
887 }
888 #endif
889 break;
890
891 }
892 default:
893 break;
894 }
895 ALOGV("receiveCameraStats X");
896 }
897
processInfoEvent(mm_camera_info_event_t * event,app_notify_cb_t * app_cb)898 void QCameraHardwareInterface::processInfoEvent(
899 mm_camera_info_event_t *event, app_notify_cb_t *app_cb) {
900 ALOGV("processInfoEvent: %d, E",event->event_id);
901 //Mutex::Autolock lock(eventLock);
902 switch(event->event_id)
903 {
904 case MM_CAMERA_INFO_EVT_ROI:
905 roiEvent(event->e.roi, app_cb);
906 break;
907 default:
908 break;
909 }
910 ALOGV("processInfoEvent: X");
911 return;
912 }
913
processEvent(mm_camera_event_t * event)914 void QCameraHardwareInterface::processEvent(mm_camera_event_t *event)
915 {
916 app_notify_cb_t app_cb;
917 ALOGV("processEvent: type :%d E",event->event_type);
918 if(mPreviewState == QCAMERA_HAL_PREVIEW_STOPPED){
919 ALOGV("Stop recording issued. Return from process Event");
920 return;
921 }
922 memset(&app_cb, 0, sizeof(app_notify_cb_t));
923 switch(event->event_type)
924 {
925 case MM_CAMERA_EVT_TYPE_CH:
926 processChannelEvent(&event->e.ch, &app_cb);
927 break;
928 case MM_CAMERA_EVT_TYPE_CTRL:
929 processCtrlEvent(&event->e.ctrl, &app_cb);
930 break;
931 case MM_CAMERA_EVT_TYPE_STATS:
932 processStatsEvent(&event->e.stats, &app_cb);
933 break;
934 case MM_CAMERA_EVT_TYPE_INFO:
935 processInfoEvent(&event->e.info, &app_cb);
936 break;
937 default:
938 break;
939 }
940 ALOGV(" App_cb Notify %p, datacb=%p", app_cb.notifyCb, app_cb.dataCb);
941 if (app_cb.notifyCb) {
942 app_cb.notifyCb(app_cb.argm_notify.msg_type,
943 app_cb.argm_notify.ext1, app_cb.argm_notify.ext2,
944 app_cb.argm_notify.cookie);
945 }
946 if (app_cb.dataCb) {
947 app_cb.dataCb(app_cb.argm_data_cb.msg_type,
948 app_cb.argm_data_cb.data, app_cb.argm_data_cb.index,
949 app_cb.argm_data_cb.metadata, app_cb.argm_data_cb.cookie);
950 }
951 ALOGV("processEvent: X");
952 return;
953 }
954
preview_parm_config(cam_ctrl_dimension_t * dim,QCameraParameters & parm)955 bool QCameraHardwareInterface::preview_parm_config (cam_ctrl_dimension_t* dim,
956 QCameraParameters& parm)
957 {
958 ALOGV("preview_parm_config: E");
959 bool matching = true;
960 int display_width = 0; /* width of display */
961 int display_height = 0; /* height of display */
962 uint16_t video_width = 0; /* width of the video */
963 uint16_t video_height = 0; /* height of the video */
964
965 /* First check if the preview resolution is the same, if not, change it*/
966 parm.getPreviewSize(&display_width, &display_height);
967 if (display_width && display_height) {
968 matching = (display_width == dim->display_width) &&
969 (display_height == dim->display_height);
970
971 if (!matching) {
972 dim->display_width = display_width;
973 dim->display_height = display_height;
974 }
975 }
976 else
977 matching = false;
978
979 cam_format_t value = getPreviewFormat();
980
981 if(value != NOT_FOUND && value != dim->prev_format ) {
982 //Setting to Parameter requested by the Upper layer
983 dim->prev_format = value;
984 } else if (value == NOT_FOUND) {
985 //Setting to default Format.
986 dim->prev_format = CAMERA_YUV_420_NV21;
987 }
988 mPreviewFormat = dim->prev_format;
989
990 dim->prev_padding_format = getPreviewPadding( );
991
992 dim->enc_format = CAMERA_YUV_420_NV12;
993 dim->orig_video_width = mDimension.orig_video_width;
994 dim->orig_video_height = mDimension.orig_video_height;
995 dim->video_width = mDimension.video_width;
996 dim->video_height = mDimension.video_height;
997 dim->video_chroma_width = mDimension.video_width;
998 dim->video_chroma_height = mDimension.video_height;
999 /* Reset the Main image and thumbnail formats here,
1000 * since they might have been changed when video size
1001 * livesnapshot was taken. */
1002 if (mSnapshotFormat == 1)
1003 dim->main_img_format = CAMERA_YUV_422_NV61;
1004 else
1005 dim->main_img_format = CAMERA_YUV_420_NV21;
1006 dim->thumb_format = CAMERA_YUV_420_NV21;
1007 ALOGV("preview_parm_config: X");
1008 return matching;
1009 }
1010
startPreview()1011 status_t QCameraHardwareInterface::startPreview()
1012 {
1013 status_t retVal = NO_ERROR;
1014
1015 ALOGV("%s: mPreviewState =%d", __func__, mPreviewState);
1016 Mutex::Autolock lock(mLock);
1017
1018 if(mPauseFramedispatch){
1019 //In ZSL case after snapshot we need to restart
1020 //if stop preview not issued.
1021 stopPreviewInternal();
1022 mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED;
1023 mPauseFramedispatch = false;
1024 }
1025
1026 switch(mPreviewState) {
1027 case QCAMERA_HAL_PREVIEW_STOPPED:
1028 case QCAMERA_HAL_TAKE_PICTURE:
1029 mPreviewState = QCAMERA_HAL_PREVIEW_START;
1030 ALOGV("%s: HAL::startPreview begin", __func__);
1031
1032 if(QCAMERA_HAL_PREVIEW_START == mPreviewState &&
1033 (mPreviewWindow)) {
1034 ALOGD("%s: start preview now", __func__);
1035 retVal = startPreview2();
1036 if(retVal == NO_ERROR)
1037 mPreviewState = QCAMERA_HAL_PREVIEW_STARTED;
1038 } else {
1039 ALOGV("%s: received startPreview, but preview window = null", __func__);
1040 }
1041 break;
1042 case QCAMERA_HAL_PREVIEW_START:
1043 case QCAMERA_HAL_PREVIEW_STARTED:
1044 break;
1045 case QCAMERA_HAL_RECORDING_STARTED:
1046 ALOGV("%s: cannot start preview in recording state", __func__);
1047 break;
1048 default:
1049 ALOGE("%s: unknow state %d received", __func__, mPreviewState);
1050 retVal = UNKNOWN_ERROR;
1051 break;
1052 }
1053 return retVal;
1054 }
1055
startPreview2()1056 status_t QCameraHardwareInterface::startPreview2()
1057 {
1058 ALOGV("startPreview2: E");
1059 status_t ret = NO_ERROR;
1060
1061 cam_ctrl_dimension_t dim;
1062 mm_camera_dimension_t maxDim;
1063 bool initPreview = false;
1064
1065 mPauseFramedispatch = false;
1066 if (mPreviewState == QCAMERA_HAL_PREVIEW_STARTED) { //isPreviewRunning()){
1067 ALOGE("%s:Preview already started mCameraState = %d!", __func__, mCameraState);
1068 ALOGV("%s: X", __func__);
1069 return NO_ERROR;
1070 }
1071
1072 const char *str = mParameters.get(QCameraParameters::KEY_SCENE_MODE);
1073
1074 if (mRecordingHint || mFlashCond || !strcmp(str, "hdr")) {
1075 ALOGI("%s:Setting non-ZSL mode",__func__);
1076 mParameters.set(QCameraParameters::KEY_CAMERA_MODE, 0);
1077 myMode = (camera_mode_t)(myMode & ~CAMERA_ZSL_MODE);
1078 mParameters.setPreviewFrameRateMode("frame-rate-auto");
1079 setPreviewFrameRateMode(mParameters);
1080 } else {
1081 ALOGI("%s:Setting ZSL mode",__func__);
1082 mParameters.set(QCameraParameters::KEY_CAMERA_MODE, 1);
1083 myMode = (camera_mode_t)(myMode | CAMERA_ZSL_MODE);
1084 mParameters.setPreviewFrameRateMode("frame-rate-auto");
1085 setPreviewFrameRateMode(mParameters);
1086
1087 }
1088
1089 /* get existing preview information, by qury mm_camera*/
1090 memset(&dim, 0, sizeof(cam_ctrl_dimension_t));
1091 ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION,&dim);
1092
1093 if (MM_CAMERA_OK != ret) {
1094 ALOGE("%s: error - can't get preview dimension!", __func__);
1095 ALOGV("%s: X", __func__);
1096 return BAD_VALUE;
1097 }
1098
1099 /* config the parmeters and see if we need to re-init the stream*/
1100 initPreview = preview_parm_config (&dim, mParameters);
1101
1102 if (mRecordingHint && mFullLiveshotEnabled) {
1103 #if 0
1104 /* Camcorder mode and Full resolution liveshot enabled
1105 * TBD lookup table for correct aspect ratio matching size */
1106 memset(&maxDim, 0, sizeof(mm_camera_dimension_t));
1107 getMaxPictureDimension(&maxDim);
1108 if (!maxDim.width || !maxDim.height) {
1109 maxDim.width = DEFAULT_LIVESHOT_WIDTH;
1110 maxDim.height = DEFAULT_LIVESHOT_HEIGHT;
1111 }
1112 /* TODO Remove this hack after adding code to get live shot dimension */
1113 if (!mCameraId) {
1114 maxDim.width = DEFAULT_LIVESHOT_WIDTH;
1115 maxDim.height = DEFAULT_LIVESHOT_HEIGHT;
1116 }
1117 dim.picture_width = maxDim.width;
1118 dim.picture_height = maxDim.height;
1119 mParameters.setPictureSize(dim.picture_width, dim.picture_height);
1120 ALOGI("%s Setting Liveshot dimension as %d x %d", __func__,
1121 maxDim.width, maxDim.height);
1122 #endif
1123 int mPictureWidth, mPictureHeight;
1124 bool matching;
1125 /* First check if the picture resolution is the same, if not, change it*/
1126 getPictureSize(&mPictureWidth, &mPictureHeight);
1127
1128 matching = (mPictureWidth == dim.picture_width) &&
1129 (mPictureHeight == dim.picture_height);
1130
1131 if (!matching) {
1132 dim.picture_width = mPictureWidth;
1133 dim.picture_height = mPictureHeight;
1134 //For FullSize snapshot Main image Buffer is used as Thumanail.
1135 dim.ui_thumbnail_height = mPictureWidth;
1136 dim.ui_thumbnail_width = mPictureHeight;
1137 }
1138 ALOGI("%s: Fullsize Liveshaot Picture size to set: %d x %d", __func__,
1139 dim.picture_width, dim.picture_height);
1140 mParameters.setPictureSize(dim.picture_width, dim.picture_height);
1141 }
1142
1143 ret = cam_config_set_parm(mCameraId, MM_CAMERA_PARM_DIMENSION,&dim);
1144 if (MM_CAMERA_OK != ret) {
1145 ALOGE("%s X: error - can't config preview parms!", __func__);
1146 return BAD_VALUE;
1147 }
1148
1149 mStreamDisplay->setMode(myMode & CAMERA_ZSL_MODE);
1150 mStreamSnap->setMode(myMode & CAMERA_ZSL_MODE);
1151 mStreamRecord->setMode(myMode & CAMERA_ZSL_MODE);
1152 ALOGV("%s: myMode = %d", __func__, myMode);
1153
1154 ALOGV("%s: setPreviewWindow", __func__);
1155 mStreamDisplay->setPreviewWindow(mPreviewWindow);
1156 ret = cam_config_set_parm(mCameraId, MM_CAMERA_PARM_INFORM_STARTPRVIEW, NULL);
1157 if(ret<0)
1158 {
1159 ALOGE("%s: Failed to Check MM_CAMERA_PARM_INFORM_STARTPRVIEW, rc %d", __func__, ret);
1160 }
1161
1162 if(isZSLMode()) {
1163 /* Start preview streaming */
1164 ret = mStreamDisplay->start();
1165 if (MM_CAMERA_OK != ret){
1166 ALOGE("%s: X -error - can't start nonZSL stream!", __func__);
1167 return BAD_VALUE;
1168 }
1169
1170 /* Start ZSL stream */
1171 ret = mStreamSnap->start();
1172 if (MM_CAMERA_OK != ret){
1173 ALOGE("%s: error - can't start Snapshot stream!", __func__);
1174 mStreamDisplay->stop();
1175 return BAD_VALUE;
1176 }
1177 }else{
1178 ret = mStreamDisplay->start();
1179 }
1180
1181 /*call QCameraStream_noneZSL::start() */
1182 if (MM_CAMERA_OK != ret){
1183 ALOGE("%s: X error - can't start stream!", __func__);
1184 return BAD_VALUE;
1185 }
1186 if(MM_CAMERA_OK == ret)
1187 mCameraState = CAMERA_STATE_PREVIEW_START_CMD_SENT;
1188 else
1189 mCameraState = CAMERA_STATE_ERROR;
1190
1191 if(mPostPreviewHeap != NULL) {
1192 mPostPreviewHeap.clear();
1193 mPostPreviewHeap = NULL;
1194 }
1195
1196 mRestartPreview = false;
1197
1198 ALOGV("startPreview: X");
1199 return ret;
1200 }
1201
stopPreview()1202 void QCameraHardwareInterface::stopPreview()
1203 {
1204 ALOGV("%s: stopPreview: E", __func__);
1205 Mutex::Autolock lock(mLock);
1206 mm_camera_util_profile("HAL: stopPreview(): E");
1207 mFaceDetectOn = false;
1208
1209 // reset recording hint to the value passed from Apps
1210 const char * str = mParameters.get(QCameraParameters::KEY_RECORDING_HINT);
1211 if((str != NULL) && !strcmp(str, "true")){
1212 mRecordingHint = true;
1213 } else {
1214 mRecordingHint = false;
1215 }
1216
1217 const char * str_fd = mParameters.get(QCameraParameters::KEY_FACE_DETECTION);
1218 if((str_fd != NULL) && !strcmp(str_fd, "on")){
1219 if(supportsFaceDetection() == false){
1220 ALOGE("Face detection support is not available");
1221 }
1222 setFaceDetection("off");
1223 runFaceDetection();
1224 }
1225
1226 switch(mPreviewState) {
1227 case QCAMERA_HAL_PREVIEW_START:
1228 //mPreviewWindow = NULL;
1229 mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED;
1230 break;
1231 case QCAMERA_HAL_PREVIEW_STARTED:
1232 stopPreviewInternal();
1233 mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED;
1234 break;
1235 case QCAMERA_HAL_RECORDING_STARTED:
1236 stopRecordingInternal();
1237 stopPreviewInternal();
1238 mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED;
1239 break;
1240 case QCAMERA_HAL_TAKE_PICTURE:
1241 cancelPictureInternal();
1242 stopPreviewInternal();
1243 mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED;
1244 break;
1245 case QCAMERA_HAL_PREVIEW_STOPPED:
1246 default:
1247 break;
1248 }
1249 ALOGV("stopPreview: X, mPreviewState = %d", mPreviewState);
1250 }
1251
1252 #if 0 //mzhu
1253 void QCameraHardwareInterface::stopPreviewZSL()
1254 {
1255 ALOGI("stopPreviewZSL: E");
1256
1257 if(!mStreamDisplay || !mStreamSnap) {
1258 ALOGE("mStreamDisplay/mStreamSnap is null");
1259 return;
1260 }
1261 ALOGI("stopPreview: X, mPreviewState = %d", mPreviewState);
1262 }
1263 #endif
stopPreviewInternal()1264 void QCameraHardwareInterface::stopPreviewInternal()
1265 {
1266 ALOGV("stopPreviewInternal: E");
1267 status_t ret = NO_ERROR;
1268
1269 if(!mStreamDisplay) {
1270 ALOGE("mStreamDisplay is null");
1271 return;
1272 }
1273
1274 if(isZSLMode()) {
1275 /* take care snapshot object for ZSL mode */
1276 mStreamSnap->stop();
1277 }
1278 mStreamDisplay->stop();
1279
1280 mPauseFramedispatch = false;
1281 mCameraState = CAMERA_STATE_PREVIEW_STOP_CMD_SENT;
1282 ALOGV("stopPreviewInternal: X");
1283 }
1284
previewEnabled()1285 int QCameraHardwareInterface::previewEnabled()
1286 {
1287 ALOGV("previewEnabled: E");
1288 Mutex::Autolock lock(mLock);
1289 ALOGV("%s: mCameraState = %d", __func__, mCameraState);
1290 if (mPauseFramedispatch) {
1291 return false;
1292 }
1293 switch(mPreviewState) {
1294 case QCAMERA_HAL_PREVIEW_STOPPED:
1295 case QCAMERA_HAL_TAKE_PICTURE:
1296 default:
1297 return false;
1298 break;
1299 case QCAMERA_HAL_PREVIEW_START:
1300 case QCAMERA_HAL_PREVIEW_STARTED:
1301 case QCAMERA_HAL_RECORDING_STARTED:
1302 return true;
1303 break;
1304 }
1305 return false;
1306 }
1307
startRecording()1308 status_t QCameraHardwareInterface::startRecording()
1309 {
1310 ALOGV("startRecording: E");
1311 status_t ret = NO_ERROR;
1312 Mutex::Autolock lock(mLock);
1313
1314 switch(mPreviewState) {
1315 case QCAMERA_HAL_PREVIEW_STOPPED:
1316 ALOGE("%s: preview has not been started", __func__);
1317 ret = UNKNOWN_ERROR;
1318 break;
1319 case QCAMERA_HAL_PREVIEW_START:
1320 ALOGE("%s: no preview native window", __func__);
1321 ret = UNKNOWN_ERROR;
1322 break;
1323 case QCAMERA_HAL_PREVIEW_STARTED:
1324 //remember recordinghint value set by app
1325 mAppRecordingHint = mRecordingHint;
1326 pausePreviewForVideo();
1327 ret = mStreamRecord->start();
1328 if (MM_CAMERA_OK != ret){
1329 ALOGE("%s: error - mStreamRecord->start!", __func__);
1330 ret = BAD_VALUE;
1331 break;
1332 }
1333 if(MM_CAMERA_OK == ret)
1334 mCameraState = CAMERA_STATE_RECORD_START_CMD_SENT;
1335 else
1336 mCameraState = CAMERA_STATE_ERROR;
1337 mPreviewState = QCAMERA_HAL_RECORDING_STARTED;
1338 break;
1339 case QCAMERA_HAL_RECORDING_STARTED:
1340 ALOGV("%s: ", __func__);
1341 break;
1342 case QCAMERA_HAL_TAKE_PICTURE:
1343 default:
1344 ret = BAD_VALUE;
1345 break;
1346 }
1347 ALOGV("startRecording: X");
1348 return ret;
1349 }
1350
stopRecording()1351 void QCameraHardwareInterface::stopRecording()
1352 {
1353 ALOGV("stopRecording: E");
1354 Mutex::Autolock lock(mLock);
1355 switch(mPreviewState) {
1356 case QCAMERA_HAL_PREVIEW_STOPPED:
1357 case QCAMERA_HAL_PREVIEW_START:
1358 case QCAMERA_HAL_PREVIEW_STARTED:
1359 break;
1360 case QCAMERA_HAL_RECORDING_STARTED:
1361 mRecordingHint = mAppRecordingHint;
1362 stopRecordingInternal();
1363 mPreviewState = QCAMERA_HAL_PREVIEW_STARTED;
1364 break;
1365 case QCAMERA_HAL_TAKE_PICTURE:
1366 default:
1367 break;
1368 }
1369 ALOGV("stopRecording: X");
1370
1371 }
stopRecordingInternal()1372 void QCameraHardwareInterface::stopRecordingInternal()
1373 {
1374 ALOGV("stopRecordingInternal: E");
1375 status_t ret = NO_ERROR;
1376
1377 if(!mStreamRecord) {
1378 ALOGE("mStreamRecord is null");
1379 return;
1380 }
1381
1382 if(mStateLiveshot && mStreamLiveSnap != NULL) {
1383 mStreamLiveSnap->stop();
1384 mStateLiveshot = false;
1385 }
1386 /*
1387 * call QCameraStream_record::stop()
1388 * Unregister Callback, action stop
1389 */
1390 mStreamRecord->stop();
1391 mCameraState = CAMERA_STATE_PREVIEW; //TODO : Apurva : Hacked for 2nd time Recording
1392 mPreviewState = QCAMERA_HAL_PREVIEW_STARTED;
1393 ALOGV("stopRecordingInternal: X");
1394 return;
1395 }
1396
recordingEnabled()1397 int QCameraHardwareInterface::recordingEnabled()
1398 {
1399 int ret = 0;
1400 Mutex::Autolock lock(mLock);
1401 ALOGV("%s: E", __func__);
1402 switch(mPreviewState) {
1403 case QCAMERA_HAL_PREVIEW_STOPPED:
1404 case QCAMERA_HAL_PREVIEW_START:
1405 case QCAMERA_HAL_PREVIEW_STARTED:
1406 break;
1407 case QCAMERA_HAL_RECORDING_STARTED:
1408 ret = 1;
1409 break;
1410 case QCAMERA_HAL_TAKE_PICTURE:
1411 default:
1412 break;
1413 }
1414 ALOGV("%s: X, ret = %d", __func__, ret);
1415 return ret; //isRecordingRunning();
1416 }
1417
1418 /**
1419 * Release a record frame previously returned by CAMERA_MSG_VIDEO_FRAME.
1420 */
releaseRecordingFrame(const void * opaque)1421 void QCameraHardwareInterface::releaseRecordingFrame(const void *opaque)
1422 {
1423 ALOGV("%s : BEGIN",__func__);
1424 if(mStreamRecord == NULL) {
1425 ALOGE("Record stream Not Initialized");
1426 return;
1427 }
1428 mStreamRecord->releaseRecordingFrame(opaque);
1429 ALOGV("%s : END",__func__);
1430 return;
1431 }
1432
autoFocusMoveEvent(cam_ctrl_status_t * status,app_notify_cb_t * app_cb)1433 status_t QCameraHardwareInterface::autoFocusMoveEvent(cam_ctrl_status_t *status, app_notify_cb_t *app_cb)
1434 {
1435 ALOGV("autoFocusMoveEvent: E");
1436 int ret = NO_ERROR;
1437
1438 isp3a_af_mode_t afMode = getAutoFocusMode(mParameters);
1439
1440 if (afMode == AF_MODE_CAF && mNotifyCb && ( mMsgEnabled & CAMERA_MSG_FOCUS_MOVE)){
1441 ALOGV("%s:Issuing AF Move callback to service",__func__);
1442
1443 app_cb->notifyCb = mNotifyCb;
1444 app_cb->argm_notify.msg_type = CAMERA_MSG_FOCUS_MOVE;
1445 app_cb->argm_notify.ext2 = 0;
1446 app_cb->argm_notify.cookie = mCallbackCookie;
1447
1448 ALOGV("Auto focus state =%d", *status);
1449 if(*status == 1) {
1450 app_cb->argm_notify.ext1 = true;
1451 }else if(*status == 0){
1452 app_cb->argm_notify.ext1 = false;
1453 }else{
1454 app_cb->notifyCb = NULL;
1455 ALOGE("%s:Unknown AF Move Status received (%d) received",__func__,*status);
1456 }
1457 }
1458 ALOGV("autoFocusMoveEvent: X");
1459 return ret;
1460 }
1461
autoFocusEvent(cam_ctrl_status_t * status,app_notify_cb_t * app_cb)1462 status_t QCameraHardwareInterface::autoFocusEvent(cam_ctrl_status_t *status, app_notify_cb_t *app_cb)
1463 {
1464 ALOGV("autoFocusEvent: E");
1465 int ret = NO_ERROR;
1466 /************************************************************
1467 BEGIN MUTEX CODE
1468 *************************************************************/
1469
1470 ALOGV("%s:%d: Trying to acquire AF bit lock",__func__,__LINE__);
1471 mAutofocusLock.lock();
1472 ALOGV("%s:%d: Acquired AF bit lock",__func__,__LINE__);
1473
1474 if(mAutoFocusRunning==false) {
1475 ALOGV("%s:AF not running, discarding stale event",__func__);
1476 mAutofocusLock.unlock();
1477 return ret;
1478 }
1479 /* If autofocus call has been made during CAF, CAF will be locked.
1480 * We specifically need to call cancelAutoFocus to unlock CAF.
1481 * In that sense, AF is still running.*/
1482 isp3a_af_mode_t afMode = getAutoFocusMode(mParameters);
1483 if (afMode == AF_MODE_CAF)
1484 mNeedToUnlockCaf = true;
1485 mAutoFocusRunning = false;
1486 mAutofocusLock.unlock();
1487
1488 /************************************************************
1489 END MUTEX CODE
1490 *************************************************************/
1491 if(status==NULL) {
1492 ALOGE("%s:NULL ptr received for status",__func__);
1493 return BAD_VALUE;
1494 }
1495
1496 /* update focus distances after autofocus is done */
1497 if((*status != CAM_CTRL_FAILED) && updateFocusDistances() != NO_ERROR) {
1498 ALOGE("%s: updateFocusDistances failed for %d", __FUNCTION__, mFocusMode);
1499 }
1500
1501 /*(Do?) we need to make sure that the call back is the
1502 last possible step in the execution flow since the same
1503 context might be used if a fail triggers another round
1504 of AF then the mAutoFocusRunning flag and other state
1505 variables' validity will be under question*/
1506
1507 if (mNotifyCb && ( mMsgEnabled & CAMERA_MSG_FOCUS)){
1508 ALOGV("%s:Issuing AF callback to service",__func__);
1509
1510 /* "Accepted" status is not appropriate it should be used for
1511 initial cmd, event reporting should only give use SUCCESS/FAIL
1512 */
1513
1514 app_cb->notifyCb = mNotifyCb;
1515 app_cb->argm_notify.msg_type = CAMERA_MSG_FOCUS;
1516 app_cb->argm_notify.ext2 = 0;
1517 app_cb->argm_notify.cookie = mCallbackCookie;
1518
1519 ALOGV("Auto focus state =%d", *status);
1520 if(*status==CAM_CTRL_SUCCESS) {
1521 app_cb->argm_notify.ext1 = true;
1522 }
1523 else if(*status==CAM_CTRL_FAILED){
1524 app_cb->argm_notify.ext1 = false;
1525 }
1526 else{
1527 app_cb->notifyCb = NULL;
1528 ALOGE("%s:Unknown AF status (%d) received",__func__,*status);
1529 }
1530
1531 }/*(mNotifyCb && ( mMsgEnabled & CAMERA_MSG_FOCUS))*/
1532 else{
1533 ALOGE("%s:Call back not enabled",__func__);
1534 }
1535
1536 ALOGV("autoFocusEvent: X");
1537 return ret;
1538
1539 }
1540
cancelPicture()1541 status_t QCameraHardwareInterface::cancelPicture()
1542 {
1543 ALOGV("cancelPicture: E");
1544 status_t ret = MM_CAMERA_OK;
1545 Mutex::Autolock lock(mLock);
1546
1547 switch(mPreviewState) {
1548 case QCAMERA_HAL_PREVIEW_STOPPED:
1549 case QCAMERA_HAL_PREVIEW_START:
1550 case QCAMERA_HAL_PREVIEW_STARTED:
1551 break;
1552 case QCAMERA_HAL_RECORDING_STARTED:
1553 if(mStateLiveshot && (mStreamLiveSnap != NULL)) {
1554 mStreamLiveSnap->stop();
1555 mStateLiveshot = false;
1556 }
1557 break;
1558 case QCAMERA_HAL_TAKE_PICTURE:
1559 ret = cancelPictureInternal();
1560 break;
1561 default:
1562 break;
1563 }
1564 ALOGV("cancelPicture: X");
1565 return ret;
1566 }
1567
cancelPictureInternal()1568 status_t QCameraHardwareInterface::cancelPictureInternal()
1569 {
1570 ALOGI("cancelPictureInternal: E");
1571 status_t ret = MM_CAMERA_OK;
1572 // Do not need Snapshot callback to up layer any more
1573 mSnapCbDisabled = true;
1574 //we should make sure that snap_jpeg_cb has finished
1575 if(mStreamSnap){
1576 mSnapJpegCbLock.lock();
1577 if(mSnapJpegCbRunning != false){
1578 ALOGE("%s: wait snapshot_jpeg_cb() to finish.", __func__);
1579 mSnapJpegCbWait.wait(mSnapJpegCbLock);
1580 ALOGE("%s: finish waiting snapshot_jpeg_cb(). ", __func__);
1581 }
1582 mSnapJpegCbLock.unlock();
1583 }
1584 ALOGI("%s: mCameraState=%d.", __func__, mCameraState);
1585 if(mCameraState != CAMERA_STATE_READY) {
1586 if(mStreamSnap) {
1587 mStreamSnap->stop();
1588 mCameraState = CAMERA_STATE_SNAP_STOP_CMD_SENT;
1589 }
1590 } else {
1591 ALOGE("%s: Cannot process cancel picture as snapshot is already done",__func__);
1592 }
1593 ALOGV("cancelPictureInternal: X");
1594 return ret;
1595 }
1596
pausePreviewForSnapshot()1597 void QCameraHardwareInterface::pausePreviewForSnapshot()
1598 {
1599 stopPreviewInternal( );
1600 }
resumePreviewAfterSnapshot()1601 status_t QCameraHardwareInterface::resumePreviewAfterSnapshot()
1602 {
1603 status_t ret = NO_ERROR;
1604 ret = mStreamDisplay->start();
1605 return ret;
1606 }
1607
liveshot_callback(mm_camera_ch_data_buf_t * recvd_frame,void * user_data)1608 void liveshot_callback(mm_camera_ch_data_buf_t *recvd_frame,
1609 void *user_data)
1610 {
1611 QCameraHardwareInterface *pme = (QCameraHardwareInterface *)user_data;
1612 cam_ctrl_dimension_t dim;
1613 int mJpegMaxSize;
1614 int mNuberOfVFEOutputs = 0;
1615 status_t ret;
1616 ALOGV("%s: E", __func__);
1617
1618 if (!pme->mStateLiveshot) {
1619 ALOGE("%s: Returning Buffer. Picture Cancelled", __func__);
1620 return;
1621 }
1622
1623 ALOGV("Live Snapshot Enabled");
1624 if (pme->mStreamLiveSnap){
1625 ALOGE("%s:Deleting old Snapshot stream instance",__func__);
1626 QCameraStream_Snapshot::deleteInstance (pme->mStreamLiveSnap);
1627 pme->mStreamLiveSnap = NULL;
1628 }
1629
1630 pme->mStreamLiveSnap = (QCameraStream_Snapshot*)QCameraStream_Snapshot::createInstance(pme->mCameraId,
1631 pme->myMode);
1632
1633 if (!pme->mStreamLiveSnap) {
1634 ALOGE("%s: error - can't creat snapshot stream!", __func__);
1635 cam_evt_buf_done(pme->mCameraId, recvd_frame);
1636 return ;
1637 }
1638 pme->mStreamLiveSnap->setModeLiveSnapshot(true);
1639 pme->mStreamLiveSnap->setHALCameraControl(pme);
1640
1641 ret = ((QCameraStream_Snapshot*)(pme->mStreamLiveSnap))->takePictureLiveshot(recvd_frame);
1642 if (MM_CAMERA_OK != ret) {
1643 ALOGE("%s: Error : returned from takePictureLiveshot",__func__);
1644 return;
1645 }
1646 pme->setCAFLockCancel();
1647 ALOGV("%s: X", __func__);
1648
1649 }
1650
takePicture()1651 status_t QCameraHardwareInterface::takePicture()
1652 {
1653 ALOGV("takePicture: E");
1654 status_t ret = MM_CAMERA_OK;
1655 int mNuberOfVFEOutputs = 0;
1656 Mutex::Autolock lock(mLock);
1657 bool hdr;
1658 int frm_num = 1, rc = 0;
1659 int exp[MAX_HDR_EXP_FRAME_NUM];
1660
1661 mSnapJpegCbLock.lock();
1662 if(mSnapJpegCbRunning==true){ // This flag is set true in snapshot_jpeg_cb
1663 ALOGE("%s: wait snapshot_jpeg_cb() to finish to proceed with the next take picture", __func__);
1664 mSnapJpegCbWait.wait(mSnapJpegCbLock);
1665 ALOGE("%s: finish waiting snapshot_jpeg_cb() ", __func__);
1666 }
1667 mSnapJpegCbLock.unlock();
1668
1669 // if we have liveSnapshot instance,
1670 // we need to delete it here to release teh channel it acquires
1671 if (NULL != mStreamLiveSnap) {
1672 delete(mStreamLiveSnap);
1673 mStreamLiveSnap = NULL;
1674 }
1675
1676 mSnapCbDisabled = false;
1677
1678 if(QCAMERA_HAL_RECORDING_STARTED != mPreviewState){
1679 isp3a_af_mode_t afMode = getAutoFocusMode(mParameters);
1680 if (!mFlashCond)
1681 {
1682 mFlashCond = getFlashCondition();
1683 }
1684 ALOGV("%s: Flash Contidion %d", __func__, mFlashCond);
1685 if(mFlashCond) {
1686 mRestartPreview = true;
1687 pausePreviewForZSL();
1688 }
1689 mFlashCond = false;
1690 }
1691
1692 rc = cam_config_set_parm(mCameraId, MM_CAMERA_PARM_LG_CAF_LOCK, NULL);
1693 if(rc<0)
1694 {
1695 ALOGE("%s: Failed to Check MM_CAMERA_PARM_LG_CAF_LOCK, rc %d", __func__, rc);
1696 }
1697 hdr = getHdrInfoAndSetExp(MAX_HDR_EXP_FRAME_NUM, &frm_num, exp);
1698
1699 mStreamSnap->resetSnapshotCounters();
1700 mStreamSnap->InitHdrInfoForSnapshot(hdr, frm_num, exp);
1701 switch(mPreviewState) {
1702 case QCAMERA_HAL_PREVIEW_STARTED:
1703 //set the fullsize liveshot to false
1704 mFullLiveshotEnabled = false;
1705 setFullLiveshot();
1706 mStreamSnap->setFullSizeLiveshot(false);
1707 if (isZSLMode()) {
1708 if (mStreamSnap != NULL) {
1709 pausePreviewForZSL();
1710 ret = mStreamSnap->takePictureZSL();
1711 if (ret != MM_CAMERA_OK) {
1712 ALOGE("%s: Error taking ZSL snapshot!", __func__);
1713 ret = BAD_VALUE;
1714 }
1715 }
1716 else {
1717 ALOGE("%s: ZSL stream not active! Failure!!", __func__);
1718 ret = BAD_VALUE;
1719 }
1720 return ret;
1721 }
1722 /*prepare snapshot, e.g LED*/
1723 takePicturePrepareHardware( );
1724 /* There's an issue where we have a glimpse of corrupted data between
1725 a time we stop a preview and display the postview. It happens because
1726 when we call stopPreview we deallocate the preview buffers hence overlay
1727 displays garbage value till we enqueue postview buffer to be displayed.
1728 Hence for temporary fix, we'll do memcopy of the last frame displayed and
1729 queue it to overlay*/
1730 // mzhu storePreviewFrameForPostview();
1731
1732 /* stop preview */
1733 pausePreviewForSnapshot();
1734
1735 /* call Snapshot start() :*/
1736 ret = mStreamSnap->start();
1737 if (MM_CAMERA_OK != ret){
1738 /* mzhu: fix me, restore preview */
1739 ALOGE("%s: error - can't start Snapshot stream!", __func__);
1740 return BAD_VALUE;
1741 }
1742
1743 if(MM_CAMERA_OK == ret)
1744 mCameraState = CAMERA_STATE_SNAP_START_CMD_SENT;
1745 else
1746 mCameraState = CAMERA_STATE_ERROR;
1747 mPreviewState = QCAMERA_HAL_TAKE_PICTURE;
1748 break;
1749 case QCAMERA_HAL_TAKE_PICTURE:
1750 break;
1751 case QCAMERA_HAL_PREVIEW_STOPPED:
1752 case QCAMERA_HAL_PREVIEW_START:
1753 ret = UNKNOWN_ERROR;
1754 break;
1755 case QCAMERA_HAL_RECORDING_STARTED:
1756 if(mStateLiveshot) {
1757 ALOGE("takePicture : Duplicate TakePicture Call");
1758 return ret;
1759 }
1760 if (canTakeFullSizeLiveshot()) {
1761 ALOGV(" Calling takeFullSizeLiveshot");
1762 takeFullSizeLiveshot();
1763 }else{
1764 ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_VFE_OUTPUT_ENABLE,
1765 &mNuberOfVFEOutputs);
1766 if (ret != MM_CAMERA_OK) {
1767 ALOGE("get parm MM_CAMERA_PARM_VFE_OUTPUT_ENABLE failed");
1768 ret = BAD_VALUE;
1769 }
1770 if (mNuberOfVFEOutputs == 1){
1771 (void) cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_PREVIEW,
1772 liveshot_callback,
1773 MM_CAMERA_REG_BUF_CB_COUNT,
1774 1,
1775 this);
1776 } else {
1777 (void) cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_VIDEO,
1778 liveshot_callback,
1779 MM_CAMERA_REG_BUF_CB_COUNT,
1780 1,
1781 this);
1782 }
1783 }
1784 mStateLiveshot = true;
1785 break;
1786 default:
1787 ret = UNKNOWN_ERROR;
1788 break;
1789 }
1790 ALOGV("takePicture: X");
1791 return ret;
1792 }
1793
canTakeFullSizeLiveshot()1794 bool QCameraHardwareInterface::canTakeFullSizeLiveshot() {
1795 bool ret;
1796 if (mFullLiveshotEnabled && !isLowPowerCamcorder()) {
1797 /* Full size liveshot enabled. */
1798
1799 /* If Picture size is same as video size, switch to Video size
1800 * live snapshot */
1801 if ((mDimension.picture_width == mVideoWidth) &&
1802 (mDimension.picture_height == mVideoHeight)) {
1803 return false;
1804 }
1805
1806 if (mDisEnabled) {
1807 /* If DIS is enabled and Picture size is
1808 * less than (video size + 10% DIS Margin)
1809 * then fall back to Video size liveshot. */
1810 if ((mDimension.picture_width <
1811 (int)(mVideoWidth * 1.1)) ||
1812 (mDimension.picture_height <
1813 (int)(mVideoHeight * 1.1))) {
1814 ret = false;
1815 } else {
1816 /* Go with Full size live snapshot. */
1817 ret = true;
1818 }
1819 } else {
1820 /* DIS Disabled. Go with Full size live snapshot */
1821 ret = true;
1822 }
1823 } else {
1824 /* Full size liveshot disabled. Fallback to Video size liveshot. */
1825 ret = false;
1826 }
1827
1828 return ret;
1829 }
1830
takeFullSizeLiveshot()1831 status_t QCameraHardwareInterface::takeFullSizeLiveshot()
1832 {
1833 status_t ret = NO_ERROR;
1834 if (mStreamLiveSnap){
1835 ALOGV("%s:Deleting old Snapshot stream instance",__func__);
1836 QCameraStream_Snapshot::deleteInstance (mStreamLiveSnap);
1837 mStreamLiveSnap = NULL;
1838 }
1839 mStreamLiveSnap = QCameraStream_Snapshot::createInstance(mCameraId, myMode);
1840
1841 if (!mStreamLiveSnap) {
1842 ALOGE("%s: error - can't creat snapshot stream!", __func__);
1843 /* mzhu: fix me, restore preview */
1844 return BAD_VALUE;
1845 }
1846
1847 /* Store HAL object in snapshot stream Object */
1848 mStreamLiveSnap->setHALCameraControl(this);
1849
1850 mStreamLiveSnap->setFullSizeLiveshot(true);
1851
1852 /* Call snapshot init*/
1853 ret = mStreamLiveSnap->init();
1854 if (MM_CAMERA_OK != ret){
1855 ALOGE("%s: error - can't init Snapshot stream!", __func__);
1856 return BAD_VALUE;
1857 }
1858
1859 /* call Snapshot start() :*/
1860 mStreamLiveSnap->resetSnapshotCounters( );
1861 ret = mStreamLiveSnap->start();
1862 if (MM_CAMERA_OK != ret){
1863 /* mzhu: fix me, restore preview */
1864 ALOGE("%s: error - can't start Snapshot stream!", __func__);
1865 return BAD_VALUE;
1866 }
1867 return ret;
1868 }
1869
takeLiveSnapshot()1870 status_t QCameraHardwareInterface::takeLiveSnapshot()
1871 {
1872 status_t ret = NO_ERROR;
1873 ALOGV("takeLiveSnapshot: E");
1874 mStreamRecord->takeLiveSnapshot();
1875 ALOGV("takeLiveSnapshot: X");
1876 return ret;
1877 }
1878
autoFocus()1879 status_t QCameraHardwareInterface::autoFocus()
1880 {
1881 ALOGV("autoFocus: E");
1882 status_t ret = NO_ERROR;
1883 mFlashCond = getFlashCondition();
1884 ALOGV("autoFocus: mFlashCond = %d", mFlashCond);
1885 Mutex::Autolock lock(mLock);
1886 ALOGV("autoFocus: Got lock");
1887 bool status = true;
1888 isp3a_af_mode_t afMode = getAutoFocusMode(mParameters);
1889
1890 Mutex::Autolock afLock(mAutofocusLock);
1891
1892 if(mAutoFocusRunning==true){
1893 ALOGV("%s:AF already running should not have got this call",__func__);
1894 return NO_ERROR;
1895 }
1896
1897 if (afMode == AF_MODE_MAX) {
1898 /* This should never happen. We cannot send a
1899 * callback notifying error from this place because
1900 * the CameraService has called this function after
1901 * acquiring the lock. So if we try to issue a callback
1902 * from this place, the callback will try to acquire
1903 * the same lock in CameraService and it will result
1904 * in deadlock. So, let the call go in to the lower
1905 * layer. The lower layer will anyway return error if
1906 * the autofocus is not supported or if the focus
1907 * value is invalid.
1908 * Just print out the error. */
1909 ALOGE("%s:Invalid AF mode (%d)", __func__, afMode);
1910 }
1911
1912 ALOGV("%s:AF start (mode %d)", __func__, afMode);
1913 if(MM_CAMERA_OK != cam_ops_action(mCameraId, true,
1914 MM_CAMERA_OPS_FOCUS, &afMode)) {
1915 ALOGE("%s: AF command failed err:%d error %s",
1916 __func__, errno, strerror(errno));
1917 return UNKNOWN_ERROR;
1918 }
1919
1920 mAutoFocusRunning = true;
1921 ALOGV("autoFocus: X");
1922 return ret;
1923 }
1924
cancelAutoFocus()1925 status_t QCameraHardwareInterface::cancelAutoFocus()
1926 {
1927 ALOGV("cancelAutoFocus: E");
1928 status_t ret = NO_ERROR;
1929 Mutex::Autolock lock(mLock);
1930
1931 /**************************************************************
1932 BEGIN MUTEX CODE
1933 *************************************************************/
1934
1935 mAutofocusLock.lock();
1936 if(mAutoFocusRunning || mNeedToUnlockCaf) {
1937 ALOGV("%s:Af either running or CAF needs unlocking", __func__);
1938 mNeedToUnlockCaf = false;
1939 mAutoFocusRunning = false;
1940 mAutofocusLock.unlock();
1941
1942 }else/*(!mAutoFocusRunning)*/{
1943
1944 mAutofocusLock.unlock();
1945 ALOGV("%s:Af not running",__func__);
1946 return NO_ERROR;
1947 }
1948 /**************************************************************
1949 END MUTEX CODE
1950 *************************************************************/
1951
1952
1953 if(MM_CAMERA_OK!=cam_ops_action(mCameraId,false,MM_CAMERA_OPS_FOCUS,NULL )) {
1954 ALOGE("%s: AF command failed err:%d error %s",__func__, errno,strerror(errno));
1955 }
1956
1957 ALOGV("cancelAutoFocus: X");
1958 return NO_ERROR;
1959 }
1960
1961 #if 0 //mzhu
1962 /*==========================================================================
1963 * FUNCTION - prepareSnapshotAndWait -
1964 *
1965 * DESCRIPTION: invoke preparesnapshot and wait for it done
1966 it can be called within takepicture, so no need
1967 to grab mLock.
1968 *=========================================================================*/
1969 void QCameraHardwareInterface::prepareSnapshotAndWait()
1970 {
1971 ALOGI("prepareSnapshotAndWait: E");
1972 int rc = 0;
1973 /*To Do: call mm camera preparesnapshot */
1974 if(!rc ) {
1975 mPreparingSnapshot = true;
1976 pthread_mutex_lock(&mAsyncCmdMutex);
1977 pthread_cond_wait(&mAsyncCmdWait, &mAsyncCmdMutex);
1978 pthread_mutex_unlock(&mAsyncCmdMutex);
1979 mPreparingSnapshot = false;
1980 }
1981 ALOGI("prepareSnapshotAndWait: X");
1982 }
1983 #endif //mzhu
1984
1985 /*==========================================================================
1986 * FUNCTION - processprepareSnapshotEvent -
1987 *
1988 * DESCRIPTION: Process the event of preparesnapshot done msg
1989 unblock prepareSnapshotAndWait( )
1990 *=========================================================================*/
processprepareSnapshotEvent(cam_ctrl_status_t * status)1991 void QCameraHardwareInterface::processprepareSnapshotEvent(cam_ctrl_status_t *status)
1992 {
1993 ALOGV("processprepareSnapshotEvent: E");
1994 pthread_mutex_lock(&mAsyncCmdMutex);
1995 pthread_cond_signal(&mAsyncCmdWait);
1996 pthread_mutex_unlock(&mAsyncCmdMutex);
1997 ALOGV("processprepareSnapshotEvent: X");
1998 }
1999
roiEvent(fd_roi_t roi,app_notify_cb_t * app_cb)2000 void QCameraHardwareInterface::roiEvent(fd_roi_t roi,app_notify_cb_t *app_cb)
2001 {
2002 ALOGV("roiEvent: E");
2003
2004 if(mStreamDisplay) mStreamDisplay->notifyROIEvent(roi);
2005 #if 0 //TODO: move to preview obj
2006 mCallbackLock.lock();
2007 data_callback mcb = mDataCb;
2008 void *mdata = mCallbackCookie;
2009 int msgEnabled = mMsgEnabled;
2010 mCallbackLock.unlock();
2011
2012 mMetaDataWaitLock.lock();
2013 if (mFaceDetectOn == true && mSendMetaData == true) {
2014 mSendMetaData = false;
2015 int faces_detected = roi.rect_num;
2016 int max_faces_detected = MAX_ROI * 4;
2017 int array[max_faces_detected + 1];
2018
2019 array[0] = faces_detected * 4;
2020 for (int i = 1, j = 0;j < MAX_ROI; j++, i = i + 4) {
2021 if (j < faces_detected) {
2022 array[i] = roi.faces[j].x;
2023 array[i+1] = roi.faces[j].y;
2024 array[i+2] = roi.faces[j].dx;
2025 array[i+3] = roi.faces[j].dy;
2026 } else {
2027 array[i] = -1;
2028 array[i+1] = -1;
2029 array[i+2] = -1;
2030 array[i+3] = -1;
2031 }
2032 }
2033 if(mMetaDataHeap != NULL){
2034 ALOGV("mMetaDataHEap is non-NULL");
2035 memcpy((uint32_t *)mMetaDataHeap->mHeap->base(), (uint32_t *)array, (sizeof(int)*(MAX_ROI*4+1)));
2036 mMetaDataWaitLock.unlock();
2037
2038 if (mcb != NULL && (msgEnabled & CAMERA_MSG_META_DATA)) {
2039 mcb(CAMERA_MSG_META_DATA, mMetaDataHeap->mBuffers[0], mdata);
2040 }
2041 } else {
2042 mMetaDataWaitLock.unlock();
2043 ALOGE("runPreviewThread mMetaDataHeap is NULL");
2044 }
2045 } else {
2046 mMetaDataWaitLock.unlock();
2047 }
2048 #endif // mzhu
2049 ALOGV("roiEvent: X");
2050 }
2051
2052
handleZoomEventForSnapshot(void)2053 void QCameraHardwareInterface::handleZoomEventForSnapshot(void)
2054 {
2055 mm_camera_ch_crop_t v4l2_crop;
2056
2057
2058 ALOGV("%s: E", __func__);
2059
2060 memset(&v4l2_crop,0,sizeof(v4l2_crop));
2061 v4l2_crop.ch_type=MM_CAMERA_CH_SNAPSHOT;
2062
2063 ALOGV("%s: Fetching crop info", __func__);
2064 cam_config_get_parm(mCameraId,MM_CAMERA_PARM_CROP,&v4l2_crop);
2065
2066 ALOGV("%s: Crop info received for main: %d, %d, %d, %d ", __func__,
2067 v4l2_crop.snapshot.main_crop.left,
2068 v4l2_crop.snapshot.main_crop.top,
2069 v4l2_crop.snapshot.main_crop.width,
2070 v4l2_crop.snapshot.main_crop.height);
2071 ALOGV("%s: Crop info received for thumbnail: %d, %d, %d, %d ",__func__,
2072 v4l2_crop.snapshot.thumbnail_crop.left,
2073 v4l2_crop.snapshot.thumbnail_crop.top,
2074 v4l2_crop.snapshot.thumbnail_crop.width,
2075 v4l2_crop.snapshot.thumbnail_crop.height);
2076
2077 if(mStreamSnap) {
2078 ALOGV("%s: Setting crop info for snapshot", __func__);
2079 memcpy(&(mStreamSnap->mCrop), &v4l2_crop, sizeof(v4l2_crop));
2080 }
2081 if(mFullLiveshotEnabled && mStreamLiveSnap){
2082 ALOGV("%s: Setting crop info for snapshot", __func__);
2083 memcpy(&(mStreamLiveSnap->mCrop), &v4l2_crop, sizeof(v4l2_crop));
2084 }
2085 ALOGV("%s: X", __func__);
2086 }
2087
handleZoomEventForPreview(app_notify_cb_t * app_cb)2088 void QCameraHardwareInterface::handleZoomEventForPreview(app_notify_cb_t *app_cb)
2089 {
2090 mm_camera_ch_crop_t v4l2_crop;
2091
2092 ALOGV("%s: E", __func__);
2093
2094 /*regular zooming or smooth zoom stopped*/
2095 if (!mSmoothZoomRunning && mPreviewWindow) {
2096 memset(&v4l2_crop, 0, sizeof(v4l2_crop));
2097 v4l2_crop.ch_type = MM_CAMERA_CH_PREVIEW;
2098
2099 ALOGV("%s: Fetching crop info", __func__);
2100 cam_config_get_parm(mCameraId,MM_CAMERA_PARM_CROP,&v4l2_crop);
2101
2102 ALOGV("%s: Crop info received: %d, %d, %d, %d ", __func__,
2103 v4l2_crop.crop.left,
2104 v4l2_crop.crop.top,
2105 v4l2_crop.crop.width,
2106 v4l2_crop.crop.height);
2107
2108 mPreviewWindow->set_crop(mPreviewWindow,
2109 v4l2_crop.crop.left,
2110 v4l2_crop.crop.top,
2111 v4l2_crop.crop.left + v4l2_crop.crop.width,
2112 v4l2_crop.crop.top + v4l2_crop.crop.height);
2113 ALOGV("%s: Done setting crop", __func__);
2114 ALOGV("%s: Currrent zoom :%d",__func__, mCurrentZoom);
2115 }
2116
2117 ALOGV("%s: X", __func__);
2118 }
2119
zoomEvent(cam_ctrl_status_t * status,app_notify_cb_t * app_cb)2120 void QCameraHardwareInterface::zoomEvent(cam_ctrl_status_t *status, app_notify_cb_t *app_cb)
2121 {
2122 ALOGV("zoomEvent: state:%d E",mPreviewState);
2123 switch (mPreviewState) {
2124 case QCAMERA_HAL_PREVIEW_STOPPED:
2125 break;
2126 case QCAMERA_HAL_PREVIEW_START:
2127 break;
2128 case QCAMERA_HAL_PREVIEW_STARTED:
2129 handleZoomEventForPreview(app_cb);
2130 if (isZSLMode())
2131 handleZoomEventForSnapshot();
2132 break;
2133 case QCAMERA_HAL_RECORDING_STARTED:
2134 handleZoomEventForPreview(app_cb);
2135 if (mFullLiveshotEnabled)
2136 handleZoomEventForSnapshot();
2137 break;
2138 case QCAMERA_HAL_TAKE_PICTURE:
2139 if(isZSLMode())
2140 handleZoomEventForPreview(app_cb);
2141 handleZoomEventForSnapshot();
2142 break;
2143 default:
2144 break;
2145 }
2146 ALOGV("zoomEvent: X");
2147 }
2148
dumpFrameToFile(const void * data,uint32_t size,char * name,char * ext,int index)2149 void QCameraHardwareInterface::dumpFrameToFile(const void * data, uint32_t size, char* name, char* ext, int index)
2150 {
2151 #if 0
2152 char buf[32], value[PROPERTY_VALUE_MAX];
2153 int file_fd, enabled = 0;
2154 static int i = 0 ;
2155 property_get("persist.camera.dumpimage", value, "0");
2156 enabled = atoi(value);
2157
2158 if ( data != NULL && enabled) {
2159 char * str;
2160 snprintf(buf, sizeof(buf), "/data/%s_%d.%s", name, index, ext);
2161 ALOGE("%s size =%d", buf, size);
2162 file_fd = open(buf, O_RDWR | O_CREAT, 0777);
2163 write(file_fd, data, size);
2164 close(file_fd);
2165 i++;
2166 }
2167 #endif
2168 }
2169
dumpFrameToFile(struct msm_frame * newFrame,HAL_cam_dump_frm_type_t frm_type)2170 void QCameraHardwareInterface::dumpFrameToFile(struct msm_frame* newFrame,
2171 HAL_cam_dump_frm_type_t frm_type)
2172 {
2173 #if 0
2174 int32_t enabled = 0;
2175 int frm_num;
2176 uint32_t skip_mode;
2177 char value[PROPERTY_VALUE_MAX];
2178 char buf[32];
2179 int main_422 = 1;
2180 property_get("persist.camera.dumpimg", value, "0");
2181 enabled = atoi(value);
2182
2183 ALOGV(" newFrame =%p, frm_type = %d", newFrame, frm_type);
2184 if(enabled & HAL_DUMP_FRM_MASK_ALL) {
2185 if((enabled & frm_type) && newFrame) {
2186 frm_num = ((enabled & 0xffff0000) >> 16);
2187 if(frm_num == 0) frm_num = 10; /*default 10 frames*/
2188 if(frm_num > 256) frm_num = 256; /*256 buffers cycle around*/
2189 skip_mode = ((enabled & 0x0000ff00) >> 8);
2190 if(skip_mode == 0) skip_mode = 1; /*no -skip */
2191
2192 if( mDumpSkipCnt % skip_mode == 0) {
2193 if (mDumpFrmCnt >= 0 && mDumpFrmCnt <= frm_num) {
2194 int w, h;
2195 int file_fd;
2196 switch (frm_type) {
2197 case HAL_DUMP_FRM_PREVIEW:
2198 w = mDimension.display_width;
2199 h = mDimension.display_height;
2200 snprintf(buf, sizeof(buf), "/data/%dp_%dx%d.yuv", mDumpFrmCnt, w, h);
2201 file_fd = open(buf, O_RDWR | O_CREAT, 0777);
2202 break;
2203 case HAL_DUMP_FRM_VIDEO:
2204 w = mVideoWidth;
2205 h = mVideoHeight;
2206 snprintf(buf, sizeof(buf),"/data/%dv_%dx%d.yuv", mDumpFrmCnt, w, h);
2207 file_fd = open(buf, O_RDWR | O_CREAT, 0777);
2208 break;
2209 case HAL_DUMP_FRM_MAIN:
2210 w = mDimension.picture_width;
2211 h = mDimension.picture_height;
2212 snprintf(buf, sizeof(buf), "/data/%dm_%dx%d.yuv", mDumpFrmCnt, w, h);
2213 file_fd = open(buf, O_RDWR | O_CREAT, 0777);
2214 if (mDimension.main_img_format == CAMERA_YUV_422_NV16 ||
2215 mDimension.main_img_format == CAMERA_YUV_422_NV61)
2216 main_422 = 2;
2217 break;
2218 case HAL_DUMP_FRM_THUMBNAIL:
2219 w = mDimension.ui_thumbnail_width;
2220 h = mDimension.ui_thumbnail_height;
2221 snprintf(buf, sizeof(buf),"/data/%dt_%dx%d.yuv", mDumpFrmCnt, w, h);
2222 file_fd = open(buf, O_RDWR | O_CREAT, 0777);
2223 break;
2224 default:
2225 w = h = 0;
2226 file_fd = -1;
2227 break;
2228 }
2229
2230 if (file_fd < 0) {
2231 ALOGE("%s: cannot open file:type=%d\n", __func__, frm_type);
2232 } else {
2233 ALOGV("%s: %d %d", __func__, newFrame->y_off, newFrame->cbcr_off);
2234 write(file_fd, (const void *)(newFrame->buffer+newFrame->y_off), w * h);
2235 write(file_fd, (const void *)
2236 (newFrame->buffer + newFrame->cbcr_off), w * h / 2 * main_422);
2237 close(file_fd);
2238 ALOGV("dump %s", buf);
2239 }
2240 } else if(frm_num == 256){
2241 mDumpFrmCnt = 0;
2242 }
2243 mDumpFrmCnt++;
2244 }
2245 mDumpSkipCnt++;
2246 }
2247 } else {
2248 mDumpFrmCnt = 0;
2249 }
2250 #endif
2251 }
2252
setPreviewWindow(preview_stream_ops_t * window)2253 status_t QCameraHardwareInterface::setPreviewWindow(preview_stream_ops_t* window)
2254 {
2255 status_t retVal = NO_ERROR;
2256 ALOGV(" %s: E mPreviewState = %d, mStreamDisplay = %p", __FUNCTION__, mPreviewState, mStreamDisplay);
2257 if( window == NULL) {
2258 ALOGE("%s:Received Setting NULL preview window", __func__);
2259 }
2260 Mutex::Autolock lock(mLock);
2261 switch(mPreviewState) {
2262 case QCAMERA_HAL_PREVIEW_START:
2263 mPreviewWindow = window;
2264 if(mPreviewWindow) {
2265 /* we have valid surface now, start preview */
2266 retVal = startPreview2();
2267 if(retVal == NO_ERROR)
2268 mPreviewState = QCAMERA_HAL_PREVIEW_STARTED;
2269 ALOGV("%s: startPreview2 done, mPreviewState = %d", __func__, mPreviewState);
2270 } else
2271 ALOGE("%s: null window received, mPreviewState = %d", __func__, mPreviewState);
2272 break;
2273 case QCAMERA_HAL_PREVIEW_STARTED:
2274 /* new window comes */
2275 ALOGE("%s: bug, cannot handle new window in started state", __func__);
2276 //retVal = UNKNOWN_ERROR;
2277 break;
2278 case QCAMERA_HAL_PREVIEW_STOPPED:
2279 case QCAMERA_HAL_TAKE_PICTURE:
2280 mPreviewWindow = window;
2281 ALOGE("%s: mPreviewWindow = 0x%p, mStreamDisplay = 0x%p",
2282 __func__, mPreviewWindow, mStreamDisplay);
2283 if(mStreamDisplay)
2284 retVal = mStreamDisplay->setPreviewWindow(window);
2285 break;
2286 default:
2287 ALOGE("%s: bug, cannot handle new window in state %d", __func__, mPreviewState);
2288 retVal = UNKNOWN_ERROR;
2289 break;
2290 }
2291 ALOGV(" %s : X, mPreviewState = %d", __FUNCTION__, mPreviewState);
2292 return retVal;
2293 }
2294
storeMetaDataInBuffers(int enable)2295 int QCameraHardwareInterface::storeMetaDataInBuffers(int enable)
2296 {
2297 /* this is a dummy func now. fix me later */
2298 mStoreMetaDataInFrame = enable;
2299 return 0;
2300 }
2301
sendMappingBuf(int ext_mode,int idx,int fd,uint32_t size,int cameraid,mm_camera_socket_msg_type msg_type)2302 status_t QCameraHardwareInterface::sendMappingBuf(int ext_mode, int idx, int fd,
2303 uint32_t size, int cameraid,
2304 mm_camera_socket_msg_type msg_type)
2305 {
2306 cam_sock_packet_t packet;
2307 memset(&packet, 0, sizeof(cam_sock_packet_t));
2308 packet.msg_type = msg_type;
2309 packet.payload.frame_fd_map.ext_mode = ext_mode;
2310 packet.payload.frame_fd_map.frame_idx = idx;
2311 packet.payload.frame_fd_map.fd = fd;
2312 packet.payload.frame_fd_map.size = size;
2313
2314 if ( cam_ops_sendmsg(cameraid, &packet, sizeof(cam_sock_packet_t), packet.payload.frame_fd_map.fd) <= 0 ) {
2315 ALOGE("%s: sending frame mapping buf msg Failed", __func__);
2316 return FAILED_TRANSACTION;
2317 }
2318 return NO_ERROR;
2319 }
2320
sendUnMappingBuf(int ext_mode,int idx,int cameraid,mm_camera_socket_msg_type msg_type)2321 status_t QCameraHardwareInterface::sendUnMappingBuf(int ext_mode, int idx, int cameraid,
2322 mm_camera_socket_msg_type msg_type)
2323 {
2324 cam_sock_packet_t packet;
2325 memset(&packet, 0, sizeof(cam_sock_packet_t));
2326 packet.msg_type = msg_type;
2327 packet.payload.frame_fd_unmap.ext_mode = ext_mode;
2328 packet.payload.frame_fd_unmap.frame_idx = idx;
2329 if ( cam_ops_sendmsg(cameraid, &packet, sizeof(cam_sock_packet_t), 0) <= 0 ) {
2330 ALOGE("%s: sending frame unmapping buf msg Failed", __func__);
2331 return FAILED_TRANSACTION;
2332 }
2333 return NO_ERROR;
2334 }
2335
allocate_ion_memory(QCameraHalHeap_t * p_camera_memory,int cnt,int ion_type)2336 int QCameraHardwareInterface::allocate_ion_memory(QCameraHalHeap_t *p_camera_memory, int cnt, int ion_type)
2337 {
2338 int rc = 0;
2339 struct ion_handle_data handle_data;
2340
2341 p_camera_memory->main_ion_fd[cnt] = open("/dev/ion", O_RDONLY);
2342 if (p_camera_memory->main_ion_fd[cnt] < 0) {
2343 ALOGE("Ion dev open failed\n");
2344 ALOGE("Error is %s\n", strerror(errno));
2345 goto ION_OPEN_FAILED;
2346 }
2347 p_camera_memory->alloc[cnt].len = p_camera_memory->size;
2348 /* to make it page size aligned */
2349 p_camera_memory->alloc[cnt].len = (p_camera_memory->alloc[cnt].len + 4095) & (~4095);
2350 p_camera_memory->alloc[cnt].align = 4096;
2351 p_camera_memory->alloc[cnt].flags = ION_FLAG_CACHED;
2352 p_camera_memory->alloc[cnt].heap_id_mask = ion_type;
2353
2354 rc = ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_ALLOC, &p_camera_memory->alloc[cnt]);
2355 if (rc < 0) {
2356 ALOGE("ION allocation failed\n");
2357 goto ION_ALLOC_FAILED;
2358 }
2359
2360 p_camera_memory->ion_info_fd[cnt].handle = p_camera_memory->alloc[cnt].handle;
2361 rc = ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_SHARE, &p_camera_memory->ion_info_fd[cnt]);
2362 if (rc < 0) {
2363 ALOGE("ION map failed %s\n", strerror(errno));
2364 goto ION_MAP_FAILED;
2365 }
2366 p_camera_memory->fd[cnt] = p_camera_memory->ion_info_fd[cnt].fd;
2367 return 0;
2368
2369 ION_MAP_FAILED:
2370 handle_data.handle = p_camera_memory->ion_info_fd[cnt].handle;
2371 ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_FREE, &handle_data);
2372 ION_ALLOC_FAILED:
2373 close(p_camera_memory->main_ion_fd[cnt]);
2374 p_camera_memory->main_ion_fd[cnt] = -1;
2375 ION_OPEN_FAILED:
2376 return -1;
2377 }
2378
deallocate_ion_memory(QCameraHalHeap_t * p_camera_memory,int cnt)2379 int QCameraHardwareInterface::deallocate_ion_memory(QCameraHalHeap_t *p_camera_memory, int cnt)
2380 {
2381 struct ion_handle_data handle_data;
2382 int rc = 0;
2383
2384 if (p_camera_memory->main_ion_fd[cnt] > 0) {
2385 handle_data.handle = p_camera_memory->ion_info_fd[cnt].handle;
2386 ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_FREE, &handle_data);
2387 close(p_camera_memory->main_ion_fd[cnt]);
2388 p_camera_memory->main_ion_fd[cnt] = -1;
2389 }
2390 return rc;
2391 }
2392
allocate_ion_memory(QCameraStatHeap_t * p_camera_memory,int cnt,int ion_type)2393 int QCameraHardwareInterface::allocate_ion_memory(QCameraStatHeap_t *p_camera_memory, int cnt, int ion_type)
2394 {
2395 int rc = 0;
2396 struct ion_handle_data handle_data;
2397
2398 p_camera_memory->main_ion_fd[cnt] = open("/dev/ion", O_RDONLY);
2399 if (p_camera_memory->main_ion_fd[cnt] < 0) {
2400 ALOGE("Ion dev open failed\n");
2401 ALOGE("Error is %s\n", strerror(errno));
2402 goto ION_OPEN_FAILED;
2403 }
2404 p_camera_memory->alloc[cnt].len = p_camera_memory->size;
2405 /* to make it page size aligned */
2406 p_camera_memory->alloc[cnt].len = (p_camera_memory->alloc[cnt].len + 4095) & (~4095);
2407 p_camera_memory->alloc[cnt].align = 4096;
2408 p_camera_memory->alloc[cnt].flags = ION_FLAG_CACHED;
2409 p_camera_memory->alloc[cnt].heap_id_mask = (0x1 << ion_type | 0x1 << ION_IOMMU_HEAP_ID);
2410
2411 rc = ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_ALLOC, &p_camera_memory->alloc[cnt]);
2412 if (rc < 0) {
2413 ALOGE("ION allocation failed\n");
2414 goto ION_ALLOC_FAILED;
2415 }
2416
2417 p_camera_memory->ion_info_fd[cnt].handle = p_camera_memory->alloc[cnt].handle;
2418 rc = ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_SHARE, &p_camera_memory->ion_info_fd[cnt]);
2419 if (rc < 0) {
2420 ALOGE("ION map failed %s\n", strerror(errno));
2421 goto ION_MAP_FAILED;
2422 }
2423 p_camera_memory->fd[cnt] = p_camera_memory->ion_info_fd[cnt].fd;
2424 return 0;
2425
2426 ION_MAP_FAILED:
2427 handle_data.handle = p_camera_memory->ion_info_fd[cnt].handle;
2428 ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_FREE, &handle_data);
2429 ION_ALLOC_FAILED:
2430 close(p_camera_memory->main_ion_fd[cnt]);
2431 p_camera_memory->main_ion_fd[cnt] = -1;
2432 ION_OPEN_FAILED:
2433 return -1;
2434 }
2435
cache_ops(int ion_fd,struct ion_flush_data * cache_data,int type)2436 int QCameraHardwareInterface::cache_ops(int ion_fd,
2437 struct ion_flush_data *cache_data, int type)
2438 {
2439 int rc = 0;
2440 struct ion_custom_data data;
2441 data.cmd = type;
2442 data.arg = (unsigned long)cache_data;
2443
2444 rc = ioctl(ion_fd, ION_IOC_CUSTOM, &data);
2445 if (rc < 0)
2446 ALOGE("%s: Cache Invalidate failed\n", __func__);
2447 else
2448 ALOGV("%s: Cache OPs type(%d) success", __func__);
2449
2450 return rc;
2451 }
2452
deallocate_ion_memory(QCameraStatHeap_t * p_camera_memory,int cnt)2453 int QCameraHardwareInterface::deallocate_ion_memory(QCameraStatHeap_t *p_camera_memory, int cnt)
2454 {
2455 struct ion_handle_data handle_data;
2456 int rc = 0;
2457
2458 if (p_camera_memory->main_ion_fd[cnt] > 0) {
2459 handle_data.handle = p_camera_memory->ion_info_fd[cnt].handle;
2460 ioctl(p_camera_memory->main_ion_fd[cnt], ION_IOC_FREE, &handle_data);
2461 close(p_camera_memory->main_ion_fd[cnt]);
2462 p_camera_memory->main_ion_fd[cnt] = -1;
2463 }
2464 return rc;
2465 }
2466
initHeapMem(QCameraHalHeap_t * heap,int num_of_buf,int buf_len,int y_off,int cbcr_off,int pmem_type,mm_cameara_stream_buf_t * StreamBuf,mm_camera_buf_def_t * buf_def,uint8_t num_planes,uint32_t * planes)2467 int QCameraHardwareInterface::initHeapMem( QCameraHalHeap_t *heap,
2468 int num_of_buf,
2469 int buf_len,
2470 int y_off,
2471 int cbcr_off,
2472 int pmem_type,
2473 mm_cameara_stream_buf_t *StreamBuf,
2474 mm_camera_buf_def_t *buf_def,
2475 uint8_t num_planes,
2476 uint32_t *planes
2477 )
2478 {
2479 int rc = 0;
2480 int i;
2481 int path;
2482 int ion_fd;
2483 struct msm_frame *frame;
2484 struct ion_flush_data cache_inv_data;
2485 ALOGV("Init Heap =%p. stream_buf =%p, pmem_type =%d, num_of_buf=%d. buf_len=%d, cbcr_off=%d",
2486 heap, StreamBuf, pmem_type, num_of_buf, buf_len, cbcr_off);
2487 if(num_of_buf > MM_CAMERA_MAX_NUM_FRAMES || heap == NULL ||
2488 mGetMemory == NULL ) {
2489 ALOGE("Init Heap error");
2490 rc = -1;
2491 return rc;
2492 }
2493 memset(heap, 0, sizeof(QCameraHalHeap_t));
2494 for (i=0; i<MM_CAMERA_MAX_NUM_FRAMES;i++) {
2495 heap->main_ion_fd[i] = -1;
2496 heap->fd[i] = -1;
2497 }
2498 heap->buffer_count = num_of_buf;
2499 heap->size = buf_len;
2500 heap->y_offset = y_off;
2501 heap->cbcr_offset = cbcr_off;
2502
2503 if (StreamBuf != NULL) {
2504 StreamBuf->num = num_of_buf;
2505 StreamBuf->frame_len = buf_len;
2506 switch (pmem_type) {
2507 case MSM_PMEM_MAINIMG:
2508 case MSM_PMEM_RAW_MAINIMG:
2509 path = OUTPUT_TYPE_S;
2510 break;
2511
2512 case MSM_PMEM_THUMBNAIL:
2513 path = OUTPUT_TYPE_T;
2514 break;
2515
2516 default:
2517 rc = -1;
2518 return rc;
2519 }
2520 }
2521
2522
2523 for(i = 0; i < num_of_buf; i++) {
2524 #ifdef USE_ION
2525 if (isZSLMode())
2526 rc = allocate_ion_memory(heap, i, ((0x1 << CAMERA_ZSL_ION_HEAP_ID) |
2527 (0x1 << CAMERA_ZSL_ION_FALLBACK_HEAP_ID)));
2528 else
2529 rc = allocate_ion_memory(heap, i, ((0x1 << CAMERA_ION_HEAP_ID) |
2530 (0x1 << CAMERA_ION_FALLBACK_HEAP_ID)));
2531
2532 if (rc < 0) {
2533 ALOGE("%s: ION allocation failed\n", __func__);
2534 break;
2535 }
2536 #else
2537 if (pmem_type == MSM_PMEM_MAX)
2538 heap->fd[i] = -1;
2539 else {
2540 heap->fd[i] = open("/dev/pmem_adsp", O_RDWR|O_SYNC);
2541 if ( heap->fd[i] <= 0) {
2542 rc = -1;
2543 ALOGE("Open fail: heap->fd[%d] =%d", i, heap->fd[i]);
2544 break;
2545 }
2546 }
2547 #endif
2548 heap->camera_memory[i] = mGetMemory( heap->fd[i], buf_len, 1, (void *)this);
2549
2550 if (heap->camera_memory[i] == NULL ) {
2551 ALOGE("Getmem fail %d: ", i);
2552 rc = -1;
2553 break;
2554 }
2555
2556 memset(&cache_inv_data, 0, sizeof(struct ion_flush_data));
2557 cache_inv_data.vaddr = (void*) heap->camera_memory[i]->data;
2558 cache_inv_data.fd = heap->ion_info_fd[i].fd;
2559 cache_inv_data.handle = heap->ion_info_fd[i].handle;
2560 cache_inv_data.length = heap->alloc[i].len;
2561 ion_fd = heap->main_ion_fd[i];
2562 if(ion_fd > 0) {
2563 if(cache_ops(ion_fd, &cache_inv_data, ION_IOC_CLEAN_INV_CACHES) < 0)
2564 ALOGE("%s: Cache Invalidate failed\n", __func__);
2565 else {
2566 ALOGV("%s: Successful cache invalidate\n", __func__);
2567 }
2568 }
2569
2570 if (StreamBuf != NULL) {
2571 frame = &(StreamBuf->frame[i]);
2572 memset(frame, 0, sizeof(struct msm_frame));
2573 frame->fd = heap->fd[i];
2574 frame->phy_offset = 0;
2575 frame->buffer = (uint32_t) heap->camera_memory[i]->data;
2576 frame->path = path;
2577 frame->cbcr_off = planes[0]+heap->cbcr_offset;
2578 frame->y_off = heap->y_offset;
2579 frame->fd_data = heap->ion_info_fd[i];
2580 frame->ion_alloc = heap->alloc[i];
2581 frame->ion_dev_fd = heap->main_ion_fd[i];
2582 ALOGV("%s: Buffer idx: %d addr: %x fd: %d phy_offset: %d"
2583 "cbcr_off: %d y_off: %d frame_len: %d", __func__,
2584 i, (unsigned int)frame->buffer, frame->fd,
2585 frame->phy_offset, cbcr_off, y_off, frame->ion_alloc.len);
2586
2587 buf_def->buf.mp[i].frame = *frame;
2588 buf_def->buf.mp[i].frame_offset = 0;
2589 buf_def->buf.mp[i].num_planes = num_planes;
2590 /* Plane 0 needs to be set seperately. Set other planes
2591 * in a loop. */
2592 buf_def->buf.mp[i].planes[0].length = planes[0];
2593 buf_def->buf.mp[i].planes[0].m.userptr = frame->fd;
2594 buf_def->buf.mp[i].planes[0].data_offset = y_off;
2595 buf_def->buf.mp[i].planes[0].reserved[0] =
2596 buf_def->buf.mp[i].frame_offset;
2597 for (int j = 1; j < num_planes; j++) {
2598 buf_def->buf.mp[i].planes[j].length = planes[j];
2599 buf_def->buf.mp[i].planes[j].m.userptr = frame->fd;
2600 buf_def->buf.mp[i].planes[j].data_offset = cbcr_off;
2601 buf_def->buf.mp[i].planes[j].reserved[0] =
2602 buf_def->buf.mp[i].planes[j-1].reserved[0] +
2603 buf_def->buf.mp[i].planes[j-1].length;
2604 }
2605 } else {
2606 }
2607
2608 ALOGV("heap->fd[%d] =%d, camera_memory=%p", i, heap->fd[i], heap->camera_memory[i]);
2609 heap->local_flag[i] = 1;
2610 }
2611 if( rc < 0) {
2612 releaseHeapMem(heap);
2613 }
2614 return rc;
2615 }
2616
releaseHeapMem(QCameraHalHeap_t * heap)2617 int QCameraHardwareInterface::releaseHeapMem( QCameraHalHeap_t *heap)
2618 {
2619 int rc = 0;
2620 ALOGV("Release %p", heap);
2621 if (heap != NULL) {
2622
2623 for (int i = 0; i < heap->buffer_count; i++) {
2624 if(heap->camera_memory[i] != NULL) {
2625 heap->camera_memory[i]->release( heap->camera_memory[i] );
2626 heap->camera_memory[i] = NULL;
2627 } else if (heap->fd[i] <= 0) {
2628 ALOGE("impossible: amera_memory[%d] = %p, fd = %d",
2629 i, heap->camera_memory[i], heap->fd[i]);
2630 }
2631
2632 if(heap->fd[i] > 0) {
2633 close(heap->fd[i]);
2634 heap->fd[i] = -1;
2635 }
2636 #ifdef USE_ION
2637 deallocate_ion_memory(heap, i);
2638 #endif
2639 }
2640 heap->buffer_count = 0;
2641 heap->size = 0;
2642 heap->y_offset = 0;
2643 heap->cbcr_offset = 0;
2644 }
2645 return rc;
2646 }
2647
getPreviewFormatInfo()2648 preview_format_info_t QCameraHardwareInterface::getPreviewFormatInfo( )
2649 {
2650 return mPreviewFormatInfo;
2651 }
2652
wdenoiseEvent(cam_ctrl_status_t status,void * cookie)2653 void QCameraHardwareInterface::wdenoiseEvent(cam_ctrl_status_t status, void *cookie)
2654 {
2655 ALOGV("wdnEvent: preview state:%d E",mPreviewState);
2656 if (mStreamSnap != NULL) {
2657 ALOGV("notifyWDNEvent to snapshot stream");
2658 mStreamSnap->notifyWDenoiseEvent(status, cookie);
2659 }
2660 }
2661
isWDenoiseEnabled()2662 bool QCameraHardwareInterface::isWDenoiseEnabled()
2663 {
2664 return mDenoiseValue;
2665 }
2666
takePicturePrepareHardware()2667 void QCameraHardwareInterface::takePicturePrepareHardware()
2668 {
2669 ALOGV("%s: E", __func__);
2670
2671 /* Prepare snapshot*/
2672 cam_ops_action(mCameraId,
2673 true,
2674 MM_CAMERA_OPS_PREPARE_SNAPSHOT,
2675 this);
2676 ALOGV("%s: X", __func__);
2677 }
2678
pausePreviewForZSL()2679 void QCameraHardwareInterface::pausePreviewForZSL()
2680 {
2681 ALOGV("%s: mRestartPreview %d", __func__, mRestartPreview);
2682 if(mRestartPreview) {
2683 ALOGE("%s: Restarting Preview",__func__);
2684 stopPreviewInternal();
2685 mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED;
2686 startPreview2();
2687 mPreviewState = QCAMERA_HAL_PREVIEW_STARTED;
2688 }
2689 }
2690
pausePreviewForVideo()2691 void QCameraHardwareInterface::pausePreviewForVideo()
2692 {
2693 status_t ret = NO_ERROR;
2694 bool restart = false;
2695 cam_ctrl_dimension_t dim;
2696
2697 /* get existing preview information, by qury mm_camera*/
2698 memset(&dim, 0, sizeof(cam_ctrl_dimension_t));
2699 ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION,&dim);
2700
2701 if (MM_CAMERA_OK != ret) {
2702 ALOGE("%s: X error- can't get preview dimension!", __func__);
2703 return;
2704 }
2705
2706 if (mRestartPreview) {
2707 mRestartPreview = false;
2708 ALOGV("%s: Restarting Preview. Video Size changed",__func__);
2709 restart |= false;
2710 }
2711 if (mRecordingHint == false) {
2712 ALOGV("%s: Restarting Preview. Hint not set",__func__);
2713 restart |= true;
2714 }
2715
2716 if(dim.video_width != mVideoWidth || dim.video_height != mVideoHeight){
2717 ALOGV("%s: Restarting Preview. New Video Size set",__func__);
2718 restart |= true;
2719 }
2720
2721 //VFE output1 shouldn't be greater than VFE output2.
2722 if( (mPreviewWidth > mVideoWidth) || (mPreviewHeight > mVideoHeight)) {
2723 //Set preview sizes as record sizes.
2724 ALOGV("Preview size %dx%d is greater than record size %dx%d,\
2725 resetting preview size to record size",mPreviewWidth,
2726 mPreviewHeight, mVideoWidth, mVideoHeight);
2727 mPreviewWidth = mVideoWidth;
2728 mPreviewHeight = mVideoHeight;
2729 mParameters.setPreviewSize(mPreviewWidth, mPreviewHeight);
2730 restart |= true;
2731 }
2732 if (restart) {
2733 stopPreviewInternal();
2734 mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED;
2735
2736 // Set recording hint to true
2737 mRecordingHint = true;
2738 setRecordingHintValue(mRecordingHint);
2739
2740 mDimension.display_width = mPreviewWidth;
2741 mDimension.display_height= mPreviewHeight;
2742 mDimension.orig_video_width = mVideoWidth;
2743 mDimension.orig_video_height = mVideoHeight;
2744 mDimension.video_width = mVideoWidth;
2745 mDimension.video_height = mVideoHeight;
2746
2747 // start preview again
2748 mPreviewState = QCAMERA_HAL_PREVIEW_START;
2749 if (startPreview2() == NO_ERROR){
2750 mPreviewState = QCAMERA_HAL_PREVIEW_STARTED;
2751 }else{
2752 ALOGE("%s: Restart for Video Failed",__func__);
2753 }
2754 }
2755 }
2756
2757 /**/
getHdrInfoAndSetExp(int max_num_frm,int * num_frame,int * exp)2758 bool QCameraHardwareInterface::getHdrInfoAndSetExp( int max_num_frm, int *num_frame, int *exp)
2759 {
2760 bool rc = false;
2761
2762 if (mHdrMode == HDR_MODE && num_frame != NULL && exp != NULL &&
2763 mRecordingHint != true &&
2764 mPreviewState != QCAMERA_HAL_RECORDING_STARTED ) {
2765 int ret = 0;
2766 *num_frame = 1;
2767 exp_bracketing_t temp;
2768 memset(&temp, 0, sizeof(exp_bracketing_t));
2769 ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_HDR, (void *)&temp );
2770 if (ret == NO_ERROR && max_num_frm > 0) {
2771 /*set as AE Bracketing mode*/
2772 temp.hdr_enable = false;
2773 temp.mode = HDR_MODE;
2774 temp.total_hal_frames = temp.total_frames;
2775 ret = native_set_parms(MM_CAMERA_PARM_HDR,
2776 sizeof(exp_bracketing_t), (void *)&temp);
2777 if (ret) {
2778 char *val, *exp_value, *prev_value;
2779 int i;
2780 exp_value = (char *) temp.values;
2781 i = 0;
2782 val = strtok_r(exp_value,",", &prev_value);
2783 while (val != NULL ){
2784 exp[i++] = atoi(val);
2785 if(i >= max_num_frm )
2786 break;
2787 val = strtok_r(NULL, ",", &prev_value);
2788 }
2789 *num_frame =temp.total_frames;
2790 rc = true;
2791 }
2792 } else {
2793 temp.total_frames = 1;
2794 }
2795 /* Application waits until this many snapshots before restarting preview */
2796 mParameters.set("num-snaps-per-shutter", 2);
2797 }
2798 return rc;
2799 }
2800
hdrEvent(cam_ctrl_status_t status,void * cookie)2801 void QCameraHardwareInterface::hdrEvent(cam_ctrl_status_t status, void *cookie)
2802 {
2803 QCameraStream * snapStream = (QCameraStream *)cookie;
2804 ALOGV("HdrEvent: preview state: E");
2805 if (snapStream != NULL && mStreamSnap != NULL) {
2806 ALOGV("HdrEvent to snapshot stream");
2807 snapStream->notifyHdrEvent(status, cookie);
2808 }
2809 }
2810
2811 }; // namespace android
2812