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