1 /* 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 19 #define LOG_TAG "QCameraHWI_Preview" 20 #include <utils/Log.h> 21 #include <utils/threads.h> 22 #include <fcntl.h> 23 #include <sys/mman.h> 24 #include "QCameraHAL.h" 25 #include "QCameraHWI.h" 26 #include <genlock.h> 27 #include <gralloc_priv.h> 28 29 #define UNLIKELY(exp) __builtin_expect(!!(exp), 0) 30 31 /* QCameraHWI_Preview class implementation goes here*/ 32 /* following code implement the preview mode's image capture & display logic of this class*/ 33 34 namespace android { 35 36 // --------------------------------------------------------------------------- 37 // Preview Callback 38 // --------------------------------------------------------------------------- 39 static void preview_notify_cb(mm_camera_ch_data_buf_t *frame, 40 void *user_data) 41 { 42 QCameraStream_preview *pme = (QCameraStream_preview *)user_data; 43 mm_camera_ch_data_buf_t *bufs_used = 0; 44 ALOGV("%s: E", __func__); 45 /* for peview data, there is no queue, so directly use*/ 46 if(pme==NULL) { 47 ALOGE("%s: X : Incorrect cookie",__func__); 48 /*Call buf done*/ 49 return; 50 } 51 52 pme->processPreviewFrame(frame); 53 ALOGV("%s: X", __func__); 54 } 55 56 status_t QCameraStream_preview::setPreviewWindow(preview_stream_ops_t* window) 57 { 58 status_t retVal = NO_ERROR; 59 ALOGV(" %s: E ", __FUNCTION__); 60 if( window == NULL) { 61 ALOGW(" Setting NULL preview window "); 62 /* TODO: Current preview window will be invalidated. 63 * Release all the buffers back */ 64 // relinquishBuffers(); 65 } 66 Mutex::Autolock lock(mStopCallbackLock); 67 mPreviewWindow = window; 68 ALOGV(" %s : X ", __FUNCTION__ ); 69 return retVal; 70 } 71 72 status_t QCameraStream_preview::getBufferFromSurface() 73 { 74 int err = 0; 75 int numMinUndequeuedBufs = 0; 76 int format = 0; 77 status_t ret = NO_ERROR; 78 int gralloc_usage; 79 80 ALOGV(" %s : E ", __FUNCTION__); 81 82 if( mPreviewWindow == NULL) { 83 ALOGE("%s: mPreviewWindow = NULL", __func__); 84 return INVALID_OPERATION; 85 } 86 cam_ctrl_dimension_t dim; 87 88 //mDisplayLock.lock(); 89 ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION,&dim); 90 91 format = mHalCamCtrl->getPreviewFormatInfo().Hal_format; 92 if(ret != NO_ERROR) { 93 ALOGE("%s: display format %d is not supported", __func__, dim.prev_format); 94 goto end; 95 } 96 numMinUndequeuedBufs = 0; 97 if(mPreviewWindow->get_min_undequeued_buffer_count) { 98 err = mPreviewWindow->get_min_undequeued_buffer_count(mPreviewWindow, &numMinUndequeuedBufs); 99 if (err != 0) { 100 ALOGE("get_min_undequeued_buffer_count failed: %s (%d)", 101 strerror(-err), -err); 102 ret = UNKNOWN_ERROR; 103 goto end; 104 } 105 } 106 mHalCamCtrl->mPreviewMemoryLock.lock(); 107 mHalCamCtrl->mPreviewMemory.buffer_count = kPreviewBufferCount + numMinUndequeuedBufs; 108 if(mHalCamCtrl->isZSLMode()) { 109 if(mHalCamCtrl->getZSLQueueDepth() > numMinUndequeuedBufs) 110 mHalCamCtrl->mPreviewMemory.buffer_count += 111 mHalCamCtrl->getZSLQueueDepth() - numMinUndequeuedBufs; 112 } 113 err = mPreviewWindow->set_buffer_count(mPreviewWindow, mHalCamCtrl->mPreviewMemory.buffer_count ); 114 if (err != 0) { 115 ALOGE("set_buffer_count failed: %s (%d)", 116 strerror(-err), -err); 117 ret = UNKNOWN_ERROR; 118 goto end; 119 } 120 err = mPreviewWindow->set_buffers_geometry(mPreviewWindow, 121 dim.display_width, dim.display_height, format); 122 if (err != 0) { 123 ALOGE("set_buffers_geometry failed: %s (%d)", 124 strerror(-err), -err); 125 ret = UNKNOWN_ERROR; 126 goto end; 127 } 128 129 ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_VFE_OUTPUT_ENABLE, &mVFEOutputs); 130 if(ret != MM_CAMERA_OK) { 131 ALOGE("get parm MM_CAMERA_PARM_VFE_OUTPUT_ENABLE failed"); 132 ret = BAD_VALUE; 133 goto end; 134 } 135 136 //as software encoder is used to encode 720p, to enhance the performance 137 //cashed pmem is used here 138 if(mVFEOutputs == 1 && dim.display_height == 720) 139 gralloc_usage = GRALLOC_USAGE_HW_CAMERA_WRITE | CAMERA_GRALLOC_HEAP_ID | CAMERA_GRALLOC_FALLBACK_HEAP_ID; 140 else 141 gralloc_usage = GRALLOC_USAGE_HW_CAMERA_WRITE | CAMERA_GRALLOC_HEAP_ID | CAMERA_GRALLOC_FALLBACK_HEAP_ID | 142 CAMERA_GRALLOC_CACHING_ID; 143 err = mPreviewWindow->set_usage(mPreviewWindow, gralloc_usage); 144 if(err != 0) { 145 /* set_usage error out */ 146 ALOGE("%s: set_usage rc = %d", __func__, err); 147 ret = UNKNOWN_ERROR; 148 goto end; 149 } 150 ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_HFR_FRAME_SKIP, &mHFRFrameSkip); 151 if(ret != MM_CAMERA_OK) { 152 ALOGE("get parm MM_CAMERA_PARM_HFR_FRAME_SKIP failed"); 153 ret = BAD_VALUE; 154 goto end; 155 } 156 for (int cnt = 0; cnt < mHalCamCtrl->mPreviewMemory.buffer_count; cnt++) { 157 int stride; 158 err = mPreviewWindow->dequeue_buffer(mPreviewWindow, 159 &mHalCamCtrl->mPreviewMemory.buffer_handle[cnt], 160 &mHalCamCtrl->mPreviewMemory.stride[cnt]); 161 if(!err) { 162 ALOGV("%s: dequeue buf hdl =%p", __func__, *mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]); 163 err = mPreviewWindow->lock_buffer(this->mPreviewWindow, 164 mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]); 165 // lock the buffer using genlock 166 ALOGV("%s: camera call genlock_lock, hdl=%p", __FUNCTION__, (*mHalCamCtrl->mPreviewMemory.buffer_handle[cnt])); 167 if (GENLOCK_NO_ERROR != genlock_lock_buffer((native_handle_t *)(*mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]), 168 GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) { 169 ALOGV("%s: genlock_lock_buffer(WRITE) failed", __FUNCTION__); 170 mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_UNLOCKED; 171 //mHalCamCtrl->mPreviewMemoryLock.unlock(); 172 //return -EINVAL; 173 } else { 174 ALOGV("%s: genlock_lock_buffer hdl =%p", __FUNCTION__, *mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]); 175 mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_LOCKED; 176 } 177 } else { 178 mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_NOT_OWNED; 179 ALOGV("%s: dequeue_buffer idx = %d err = %d", __func__, cnt, err); 180 } 181 182 ALOGV("%s: dequeue buf: %p\n", __func__, mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]); 183 184 if(err != 0) { 185 ALOGE("%s: dequeue_buffer failed: %s (%d)", __func__, 186 strerror(-err), -err); 187 ret = UNKNOWN_ERROR; 188 for(int i = 0; i < cnt; i++) { 189 if (BUFFER_LOCKED == mHalCamCtrl->mPreviewMemory.local_flag[i]) { 190 ALOGV("%s: camera call genlock_unlock", __FUNCTION__); 191 if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t *) 192 (*(mHalCamCtrl->mPreviewMemory.buffer_handle[i])))) { 193 ALOGE("%s: genlock_unlock_buffer failed: hdl =%p", __FUNCTION__, (*(mHalCamCtrl->mPreviewMemory.buffer_handle[i])) ); 194 //mHalCamCtrl->mPreviewMemoryLock.unlock(); 195 //return -EINVAL; 196 } else { 197 mHalCamCtrl->mPreviewMemory.local_flag[i] = BUFFER_UNLOCKED; 198 } 199 } 200 if( mHalCamCtrl->mPreviewMemory.local_flag[i] != BUFFER_NOT_OWNED) { 201 err = mPreviewWindow->cancel_buffer(mPreviewWindow, 202 mHalCamCtrl->mPreviewMemory.buffer_handle[i]); 203 } 204 mHalCamCtrl->mPreviewMemory.local_flag[i] = BUFFER_NOT_OWNED; 205 ALOGV("%s: cancel_buffer: hdl =%p", __func__, (*mHalCamCtrl->mPreviewMemory.buffer_handle[i])); 206 mHalCamCtrl->mPreviewMemory.buffer_handle[i] = NULL; 207 } 208 memset(&mHalCamCtrl->mPreviewMemory, 0, sizeof(mHalCamCtrl->mPreviewMemory)); 209 goto end; 210 } 211 212 mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt] = 213 (struct private_handle_t *)(*mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]); 214 #ifdef USE_ION 215 mHalCamCtrl->mPreviewMemory.main_ion_fd[cnt] = open("/dev/ion", O_RDONLY); 216 if (mHalCamCtrl->mPreviewMemory.main_ion_fd[cnt] < 0) { 217 ALOGE("%s: failed: could not open ion device\n", __func__); 218 } else { 219 mHalCamCtrl->mPreviewMemory.ion_info_fd[cnt].fd = 220 mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->fd; 221 if (ioctl(mHalCamCtrl->mPreviewMemory.main_ion_fd[cnt], 222 ION_IOC_IMPORT, &mHalCamCtrl->mPreviewMemory.ion_info_fd[cnt]) < 0) 223 ALOGE("ION import failed\n"); 224 } 225 #endif 226 mHalCamCtrl->mPreviewMemory.camera_memory[cnt] = 227 mHalCamCtrl->mGetMemory(mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->fd, 228 mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->size, 1, (void *)this); 229 ALOGV("%s: idx = %d, fd = %d, size = %d, offset = %d", __func__, 230 cnt, mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->fd, 231 mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->size, 232 mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->offset); 233 } 234 235 //Cancel min_undequeued_buffer buffers back to the window 236 for (int i = 0; i < numMinUndequeuedBufs; i ++) { 237 if( mHalCamCtrl->mPreviewMemory.local_flag[i] != BUFFER_NOT_OWNED) { 238 err = mPreviewWindow->cancel_buffer(mPreviewWindow, mHalCamCtrl->mPreviewMemory.buffer_handle[i]); 239 } 240 mHalCamCtrl->mPreviewMemory.local_flag[i] = BUFFER_NOT_OWNED; 241 } 242 243 memset(&mHalCamCtrl->mMetadata, 0, sizeof(mHalCamCtrl->mMetadata)); 244 memset(mHalCamCtrl->mFace, 0, sizeof(mHalCamCtrl->mFace)); 245 246 ALOGV(" %s : X ",__FUNCTION__); 247 end: 248 //mDisplayLock.unlock(); 249 mHalCamCtrl->mPreviewMemoryLock.unlock(); 250 251 return ret; 252 } 253 254 status_t QCameraStream_preview::putBufferToSurface() { 255 int err = 0; 256 status_t ret = NO_ERROR; 257 258 ALOGV(" %s : E ", __FUNCTION__); 259 260 mHalCamCtrl->mPreviewMemoryLock.lock(); 261 for (int cnt = 0; cnt < mHalCamCtrl->mPreviewMemory.buffer_count; cnt++) { 262 if (cnt < mHalCamCtrl->mPreviewMemory.buffer_count) { 263 if (NO_ERROR != mHalCamCtrl->sendUnMappingBuf(MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW, cnt, mCameraId, 264 CAM_SOCK_MSG_TYPE_FD_UNMAPPING)) { 265 ALOGE("%s: unmapping Preview Buffer", __func__); 266 } 267 if(mHalCamCtrl->isZSLMode()) { 268 if (NO_ERROR != mHalCamCtrl->sendUnMappingBuf(MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL, cnt, mCameraId, 269 CAM_SOCK_MSG_TYPE_FD_UNMAPPING)) { 270 ALOGE("%s: unmapping Thumbnail Buffer for ZSL", __func__); 271 } 272 } 273 } 274 275 mHalCamCtrl->mPreviewMemory.camera_memory[cnt]->release(mHalCamCtrl->mPreviewMemory.camera_memory[cnt]); 276 #ifdef USE_ION 277 struct ion_handle_data ion_handle; 278 ion_handle.handle = mHalCamCtrl->mPreviewMemory.ion_info_fd[cnt].handle; 279 if (ioctl(mHalCamCtrl->mPreviewMemory.main_ion_fd[cnt], ION_IOC_FREE, &ion_handle) 280 < 0) 281 ALOGE("%s: ion free failed\n", __func__); 282 close(mHalCamCtrl->mPreviewMemory.main_ion_fd[cnt]); 283 #endif 284 if (BUFFER_LOCKED == mHalCamCtrl->mPreviewMemory.local_flag[cnt]) { 285 ALOGV("%s: camera call genlock_unlock", __FUNCTION__); 286 if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t *) 287 (*(mHalCamCtrl->mPreviewMemory.buffer_handle[cnt])))) { 288 ALOGE("%s: genlock_unlock_buffer failed, handle =%p", __FUNCTION__, (*(mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]))); 289 continue; 290 //mHalCamCtrl->mPreviewMemoryLock.unlock(); 291 //return -EINVAL; 292 } else { 293 294 ALOGV("%s: genlock_unlock_buffer, handle =%p", __FUNCTION__, (*(mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]))); 295 mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_UNLOCKED; 296 } 297 } 298 if( mHalCamCtrl->mPreviewMemory.local_flag[cnt] != BUFFER_NOT_OWNED) { 299 err = mPreviewWindow->cancel_buffer(mPreviewWindow, mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]); 300 ALOGV("%s: cancel_buffer: hdl =%p", __func__, (*mHalCamCtrl->mPreviewMemory.buffer_handle[cnt])); 301 } 302 mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_NOT_OWNED; 303 304 ALOGV(" put buffer %d successfully", cnt); 305 } 306 307 if (mDisplayBuf.preview.buf.mp != NULL) { 308 delete[] mDisplayBuf.preview.buf.mp; 309 mDisplayBuf.preview.buf.mp = NULL; 310 } 311 312 mHalCamCtrl->mPreviewMemoryLock.unlock(); 313 memset(&mHalCamCtrl->mPreviewMemory, 0, sizeof(mHalCamCtrl->mPreviewMemory)); 314 ALOGV(" %s : X ",__FUNCTION__); 315 return NO_ERROR; 316 } 317 318 319 status_t QCameraStream_preview::getBufferNoDisplay( ) 320 { 321 int err = 0; 322 status_t ret = NO_ERROR; 323 int i, num_planes, frame_len, y_off, cbcr_off; 324 cam_ctrl_dimension_t dim; 325 uint32_t planes[VIDEO_MAX_PLANES]; 326 327 ALOGV("%s : E ", __FUNCTION__); 328 329 330 ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION, &dim); 331 if(ret != NO_ERROR) { 332 ALOGE("%s: display format %d is not supported", __func__, dim.prev_format); 333 goto end; 334 } 335 mHalCamCtrl->mPreviewMemoryLock.lock(); 336 mHalCamCtrl->mNoDispPreviewMemory.buffer_count = kPreviewBufferCount; 337 if(mHalCamCtrl->isZSLMode()) { 338 if(mHalCamCtrl->getZSLQueueDepth() > kPreviewBufferCount - 3) 339 mHalCamCtrl->mNoDispPreviewMemory.buffer_count = 340 mHalCamCtrl->getZSLQueueDepth() + 3; 341 } 342 343 num_planes = dim.display_frame_offset.num_planes; 344 for ( i = 0; i < num_planes; i++) { 345 planes[i] = dim.display_frame_offset.mp[i].len; 346 } 347 348 frame_len = dim.picture_frame_offset.frame_len; 349 y_off = dim.picture_frame_offset.mp[0].offset; 350 cbcr_off = dim.picture_frame_offset.mp[1].offset; 351 ALOGV("%s: main image: rotation = %d, yoff = %d, cbcroff = %d, size = %d, width = %d, height = %d", 352 __func__, dim.rotation, y_off, cbcr_off, frame_len, 353 dim.display_width, dim.display_height); 354 if (mHalCamCtrl->initHeapMem(&mHalCamCtrl->mNoDispPreviewMemory, 355 mHalCamCtrl->mNoDispPreviewMemory.buffer_count, 356 frame_len, y_off, cbcr_off, MSM_PMEM_MAINIMG, 357 NULL,NULL, num_planes, planes) < 0) { 358 ret = NO_MEMORY; 359 goto end; 360 }; 361 362 memset(&mHalCamCtrl->mMetadata, 0, sizeof(mHalCamCtrl->mMetadata)); 363 memset(mHalCamCtrl->mFace, 0, sizeof(mHalCamCtrl->mFace)); 364 365 ALOGV(" %s : X ",__FUNCTION__); 366 end: 367 //mDisplayLock.unlock(); 368 mHalCamCtrl->mPreviewMemoryLock.unlock(); 369 370 return NO_ERROR; 371 } 372 373 status_t QCameraStream_preview::freeBufferNoDisplay() 374 { 375 int err = 0; 376 status_t ret = NO_ERROR; 377 378 ALOGV(" %s : E ", __FUNCTION__); 379 380 //mDisplayLock.lock(); 381 mHalCamCtrl->mPreviewMemoryLock.lock(); 382 for (int cnt = 0; cnt < mHalCamCtrl->mNoDispPreviewMemory.buffer_count; cnt++) { 383 if (cnt < mHalCamCtrl->mNoDispPreviewMemory.buffer_count) { 384 if (NO_ERROR != mHalCamCtrl->sendUnMappingBuf(MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW, 385 cnt, mCameraId, CAM_SOCK_MSG_TYPE_FD_UNMAPPING)) { 386 ALOGE("%s: sending data Msg Failed", __func__); 387 } 388 if(mHalCamCtrl->isZSLMode()) { 389 if (NO_ERROR != mHalCamCtrl->sendUnMappingBuf(MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL, cnt, mCameraId, 390 CAM_SOCK_MSG_TYPE_FD_UNMAPPING)) { 391 ALOGE("%s: Send socket msg to Unmap Failed", __func__); 392 } 393 } 394 } 395 } 396 mHalCamCtrl->releaseHeapMem(&mHalCamCtrl->mNoDispPreviewMemory); 397 memset(&mHalCamCtrl->mNoDispPreviewMemory, 0, sizeof(mHalCamCtrl->mNoDispPreviewMemory)); 398 if (mDisplayBuf.preview.buf.mp != NULL) { 399 delete[] mDisplayBuf.preview.buf.mp; 400 mDisplayBuf.preview.buf.mp = NULL; 401 } 402 403 mHalCamCtrl->mPreviewMemoryLock.unlock(); 404 ALOGV(" %s : X ",__FUNCTION__); 405 return NO_ERROR; 406 } 407 408 void QCameraStream_preview::notifyROIEvent(fd_roi_t roi) 409 { 410 camera_memory_t *data = mHalCamCtrl->mGetMemory(-1, 1, 1, NULL); 411 switch (roi.type) { 412 case FD_ROI_TYPE_HEADER: 413 { 414 mDisplayLock.lock(); 415 mNumFDRcvd = 0; 416 memset(mHalCamCtrl->mFace, 0, sizeof(mHalCamCtrl->mFace)); 417 mHalCamCtrl->mMetadata.faces = mHalCamCtrl->mFace; 418 mHalCamCtrl->mMetadata.number_of_faces = roi.d.hdr.num_face_detected; 419 if(mHalCamCtrl->mMetadata.number_of_faces > MAX_ROI) 420 mHalCamCtrl->mMetadata.number_of_faces = MAX_ROI; 421 mDisplayLock.unlock(); 422 423 if (mHalCamCtrl->mMetadata.number_of_faces == 0) { 424 // Clear previous faces 425 mHalCamCtrl->mCallbackLock.lock(); 426 camera_data_callback pcb = mHalCamCtrl->mDataCb; 427 mHalCamCtrl->mCallbackLock.unlock(); 428 429 if (pcb && (mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_METADATA)){ 430 ALOGV("%s: Face detection RIO callback", __func__); 431 pcb(CAMERA_MSG_PREVIEW_METADATA, data, 0, &mHalCamCtrl->mMetadata, mHalCamCtrl->mCallbackCookie); 432 } 433 } 434 } 435 break; 436 case FD_ROI_TYPE_DATA: 437 { 438 #if 1 439 mDisplayLock.lock(); 440 int idx = roi.d.data.idx; 441 if (idx >= mHalCamCtrl->mMetadata.number_of_faces) { 442 mDisplayLock.unlock(); 443 ALOGE("%s: idx %d out of boundary %d", __func__, idx, mHalCamCtrl->mMetadata.number_of_faces); 444 break; 445 } 446 447 mHalCamCtrl->mFace[idx].id = roi.d.data.face.id; 448 mHalCamCtrl->mFace[idx].score = roi.d.data.face.score; 449 450 // top 451 mHalCamCtrl->mFace[idx].rect[0] = 452 roi.d.data.face.face_boundary.x*2000/mHalCamCtrl->mDimension.display_width - 1000; 453 //right 454 mHalCamCtrl->mFace[idx].rect[1] = 455 roi.d.data.face.face_boundary.y*2000/mHalCamCtrl->mDimension.display_height - 1000; 456 //bottom 457 mHalCamCtrl->mFace[idx].rect[2] = mHalCamCtrl->mFace[idx].rect[0] + 458 roi.d.data.face.face_boundary.dx*2000/mHalCamCtrl->mDimension.display_width; 459 //left 460 mHalCamCtrl->mFace[idx].rect[3] = mHalCamCtrl->mFace[idx].rect[1] + 461 roi.d.data.face.face_boundary.dy*2000/mHalCamCtrl->mDimension.display_height; 462 463 // Center of left eye 464 mHalCamCtrl->mFace[idx].left_eye[0] = 465 roi.d.data.face.left_eye_center[0]*2000/mHalCamCtrl->mDimension.display_width - 1000; 466 mHalCamCtrl->mFace[idx].left_eye[1] = 467 roi.d.data.face.left_eye_center[1]*2000/mHalCamCtrl->mDimension.display_height - 1000; 468 469 // Center of right eye 470 mHalCamCtrl->mFace[idx].right_eye[0] = 471 roi.d.data.face.right_eye_center[0]*2000/mHalCamCtrl->mDimension.display_width - 1000; 472 mHalCamCtrl->mFace[idx].right_eye[1] = 473 roi.d.data.face.right_eye_center[1]*2000/mHalCamCtrl->mDimension.display_height - 1000; 474 #if 0 475 // Center of mouth 476 mHalCamCtrl->mFace[idx].mouth[0] = 477 roi.d.data.face.mouth_center[0]*2000/mHalCamCtrl->mDimension.display_width - 1000; 478 mHalCamCtrl->mFace[idx].mouth[1] = 479 roi.d.data.face.mouth_center[1]*2000/mHalCamCtrl->mDimension.display_height - 1000; 480 481 mHalCamCtrl->mFace[idx].smile_degree = roi.d.data.face.smile_degree; 482 mHalCamCtrl->mFace[idx].smile_score = roi.d.data.face.smile_confidence; 483 mHalCamCtrl->mFace[idx].blink_detected = roi.d.data.face.blink_detected; 484 mHalCamCtrl->mFace[idx].face_recognised = roi.d.data.face.is_face_recognised; 485 mHalCamCtrl->mFace[idx].gaze_angle = roi.d.data.face.gaze_angle; 486 487 /* newly added */ 488 // upscale by 2 to recover from demaen downscaling 489 mHalCamCtrl->mFace[idx].updown_dir = roi.d.data.face.updown_dir*2; 490 mHalCamCtrl->mFace[idx].leftright_dir = roi.d.data.face.leftright_dir*2; 491 mHalCamCtrl->mFace[idx].roll_dir = roi.d.data.face.roll_dir*2; 492 493 mHalCamCtrl->mFace[idx].leye_blink = roi.d.data.face.left_blink; 494 mHalCamCtrl->mFace[idx].reye_blink = roi.d.data.face.right_blink; 495 mHalCamCtrl->mFace[idx].left_right_gaze = roi.d.data.face.left_right_gaze; 496 mHalCamCtrl->mFace[idx].top_bottom_gaze = roi.d.data.face.top_bottom_gaze; 497 ALOGE("%s: Face(%d, %d, %d, %d), leftEye(%d, %d), rightEye(%d, %d), mouth(%d, %d), smile(%d, %d), face_recg(%d)", __func__, 498 mHalCamCtrl->mFace[idx].rect[0], mHalCamCtrl->mFace[idx].rect[1], 499 mHalCamCtrl->mFace[idx].rect[2], mHalCamCtrl->mFace[idx].rect[3], 500 mHalCamCtrl->mFace[idx].left_eye[0], mHalCamCtrl->mFace[idx].left_eye[1], 501 mHalCamCtrl->mFace[idx].right_eye[0], mHalCamCtrl->mFace[idx].right_eye[1], 502 mHalCamCtrl->mFace[idx].mouth[0], mHalCamCtrl->mFace[idx].mouth[1], 503 mHalCamCtrl->mFace[idx].smile_degree, mHalCamCtrl->mFace[idx].smile_score, 504 mHalCamCtrl->mFace[idx].face_recognised); 505 ALOGE("%s: gaze(%d, %d, %d), updown(%d), leftright(%d), roll(%d), blink(%d, %d, %d)", __func__, 506 mHalCamCtrl->mFace[idx].gaze_angle, mHalCamCtrl->mFace[idx].left_right_gaze, 507 mHalCamCtrl->mFace[idx].top_bottom_gaze, mHalCamCtrl->mFace[idx].updown_dir, 508 mHalCamCtrl->mFace[idx].leftright_dir, mHalCamCtrl->mFace[idx].roll_dir, 509 mHalCamCtrl->mFace[idx].blink_detected, 510 mHalCamCtrl->mFace[idx].leye_blink, mHalCamCtrl->mFace[idx].reye_blink); 511 #endif 512 mNumFDRcvd++; 513 mDisplayLock.unlock(); 514 515 if (mNumFDRcvd == mHalCamCtrl->mMetadata.number_of_faces) { 516 mHalCamCtrl->mCallbackLock.lock(); 517 camera_data_callback pcb = mHalCamCtrl->mDataCb; 518 mHalCamCtrl->mCallbackLock.unlock(); 519 520 if (pcb && (mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_METADATA)){ 521 ALOGV("%s: Face detection RIO callback with %d faces detected (score=%d)", __func__, mNumFDRcvd, mHalCamCtrl->mFace[idx].score); 522 pcb(CAMERA_MSG_PREVIEW_METADATA, data, 0, &mHalCamCtrl->mMetadata, mHalCamCtrl->mCallbackCookie); 523 } 524 } 525 #endif 526 } 527 break; 528 } 529 if(NULL != data) data->release(data); 530 } 531 532 status_t QCameraStream_preview::initDisplayBuffers() 533 { 534 status_t ret = NO_ERROR; 535 int width = 0; /* width of channel */ 536 int height = 0; /* height of channel */ 537 uint32_t frame_len = 0; /* frame planner length */ 538 int buffer_num = 4, i; /* number of buffers for display */ 539 const char *pmem_region; 540 uint8_t num_planes = 0; 541 uint32_t planes[VIDEO_MAX_PLANES]; 542 void *vaddr = NULL; 543 cam_ctrl_dimension_t dim; 544 545 ALOGV("%s:BEGIN",__func__); 546 memset(&mHalCamCtrl->mMetadata, 0, sizeof(camera_frame_metadata_t)); 547 mHalCamCtrl->mPreviewMemoryLock.lock(); 548 memset(&mHalCamCtrl->mPreviewMemory, 0, sizeof(mHalCamCtrl->mPreviewMemory)); 549 mHalCamCtrl->mPreviewMemoryLock.unlock(); 550 memset(&mNotifyBuffer, 0, sizeof(mNotifyBuffer)); 551 552 /* get preview size, by qury mm_camera*/ 553 memset(&dim, 0, sizeof(cam_ctrl_dimension_t)); 554 555 memset(&(this->mDisplayStreamBuf),0, sizeof(this->mDisplayStreamBuf)); 556 557 ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION, &dim); 558 if (MM_CAMERA_OK != ret) { 559 ALOGE("%s: error - can't get camera dimension!", __func__); 560 ALOGV("%s: X", __func__); 561 return BAD_VALUE; 562 }else { 563 width = dim.display_width, 564 height = dim.display_height; 565 } 566 567 ret = getBufferFromSurface(); 568 if(ret != NO_ERROR) { 569 ALOGE("%s: cannot get memory from surface texture client, ret = %d", __func__, ret); 570 return ret; 571 } 572 573 /* set 4 buffers for display */ 574 mHalCamCtrl->mPreviewMemoryLock.lock(); 575 memset(&mDisplayStreamBuf, 0, sizeof(mDisplayStreamBuf)); 576 this->mDisplayStreamBuf.num = mHalCamCtrl->mPreviewMemory.buffer_count; 577 this->myMode=myMode; /*Need to assign this in constructor after translating from mask*/ 578 num_planes = dim.display_frame_offset.num_planes; 579 for(i =0; i< num_planes; i++) { 580 planes[i] = dim.display_frame_offset.mp[i].len; 581 } 582 this->mDisplayStreamBuf.frame_len = dim.display_frame_offset.frame_len; 583 584 memset(&mDisplayBuf, 0, sizeof(mDisplayBuf)); 585 mDisplayBuf.preview.buf.mp = new mm_camera_mp_buf_t[mDisplayStreamBuf.num]; 586 if (!mDisplayBuf.preview.buf.mp) { 587 ALOGE("%s Error allocating memory for mplanar struct ", __func__); 588 ret = NO_MEMORY; 589 goto error; 590 } 591 memset(mDisplayBuf.preview.buf.mp, 0, 592 mDisplayStreamBuf.num * sizeof(mm_camera_mp_buf_t)); 593 594 /*allocate memory for the buffers*/ 595 for(int i = 0; i < mDisplayStreamBuf.num; i++){ 596 if (mHalCamCtrl->mPreviewMemory.private_buffer_handle[i] == NULL) 597 continue; 598 mDisplayStreamBuf.frame[i].fd = mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->fd; 599 mDisplayStreamBuf.frame[i].cbcr_off = planes[0]; 600 mDisplayStreamBuf.frame[i].y_off = 0; 601 mDisplayStreamBuf.frame[i].path = OUTPUT_TYPE_P; 602 mHalCamCtrl->mPreviewMemory.addr_offset[i] = 603 mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->offset; 604 mDisplayStreamBuf.frame[i].buffer = 605 (long unsigned int)mHalCamCtrl->mPreviewMemory.camera_memory[i]->data; 606 mDisplayStreamBuf.frame[i].ion_alloc.len = mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->size; 607 mDisplayStreamBuf.frame[i].ion_dev_fd = mHalCamCtrl->mPreviewMemory.main_ion_fd[i]; 608 mDisplayStreamBuf.frame[i].fd_data = mHalCamCtrl->mPreviewMemory.ion_info_fd[i]; 609 610 ALOGV("%s: idx = %d, fd = %d, size = %d, cbcr_offset = %d, y_offset = %d, " 611 "offset = %d, vaddr = 0x%x", __func__, i, mDisplayStreamBuf.frame[i].fd, 612 mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->size, 613 mDisplayStreamBuf.frame[i].cbcr_off, mDisplayStreamBuf.frame[i].y_off, 614 mHalCamCtrl->mPreviewMemory.addr_offset[i], 615 (uint32_t)mDisplayStreamBuf.frame[i].buffer); 616 617 ret = mHalCamCtrl->sendMappingBuf( 618 MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW, 619 i, 620 mDisplayStreamBuf.frame[i].fd, 621 mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->size, 622 mCameraId, CAM_SOCK_MSG_TYPE_FD_MAPPING); 623 if (NO_ERROR != ret) { 624 ALOGE("%s: sending mapping data Msg Failed", __func__); 625 goto error; 626 } 627 628 if(mHalCamCtrl->isZSLMode()) { 629 ret = mHalCamCtrl->sendMappingBuf( 630 MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL, 631 i, 632 mDisplayStreamBuf.frame[i].fd, 633 mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->size, 634 mCameraId, CAM_SOCK_MSG_TYPE_FD_MAPPING); 635 if (NO_ERROR != ret) { 636 ALOGE("%s: Send socket msg to map Failed", __func__); 637 goto error; 638 } 639 } 640 mDisplayBuf.preview.buf.mp[i].frame = mDisplayStreamBuf.frame[i]; 641 mDisplayBuf.preview.buf.mp[i].frame_offset = mHalCamCtrl->mPreviewMemory.addr_offset[i]; 642 mDisplayBuf.preview.buf.mp[i].num_planes = num_planes; 643 644 /* Plane 0 needs to be set seperately. Set other planes 645 * in a loop. */ 646 mDisplayBuf.preview.buf.mp[i].planes[0].length = planes[0]; 647 mDisplayBuf.preview.buf.mp[i].planes[0].m.userptr = mDisplayStreamBuf.frame[i].fd; 648 mDisplayBuf.preview.buf.mp[i].planes[0].data_offset = 0; 649 mDisplayBuf.preview.buf.mp[i].planes[0].reserved[0] = 650 mDisplayBuf.preview.buf.mp[i].frame_offset; 651 for (int j = 1; j < num_planes; j++) { 652 mDisplayBuf.preview.buf.mp[i].planes[j].length = planes[j]; 653 mDisplayBuf.preview.buf.mp[i].planes[j].m.userptr = 654 mDisplayStreamBuf.frame[i].fd; 655 mDisplayBuf.preview.buf.mp[i].planes[j].data_offset = 0; 656 mDisplayBuf.preview.buf.mp[i].planes[j].reserved[0] = 657 mDisplayBuf.preview.buf.mp[i].planes[j-1].reserved[0] + 658 mDisplayBuf.preview.buf.mp[i].planes[j-1].length; 659 } 660 661 for (int j = 0; j < num_planes; j++) 662 ALOGV("Planes: %d length: %d userptr: %lu offset: %d\n", j, 663 mDisplayBuf.preview.buf.mp[i].planes[j].length, 664 mDisplayBuf.preview.buf.mp[i].planes[j].m.userptr, 665 mDisplayBuf.preview.buf.mp[i].planes[j].reserved[0]); 666 }/*end of for loop*/ 667 668 /* register the streaming buffers for the channel*/ 669 mDisplayBuf.ch_type = MM_CAMERA_CH_PREVIEW; 670 mDisplayBuf.preview.num = mDisplayStreamBuf.num; 671 mHalCamCtrl->mPreviewMemoryLock.unlock(); 672 ALOGV("%s:END",__func__); 673 return NO_ERROR; 674 675 error: 676 mHalCamCtrl->mPreviewMemoryLock.unlock(); 677 putBufferToSurface(); 678 679 ALOGV("%s: X", __func__); 680 return ret; 681 } 682 683 status_t QCameraStream_preview::initPreviewOnlyBuffers() 684 { 685 status_t ret = NO_ERROR; 686 int width = 0; /* width of channel */ 687 int height = 0; /* height of channel */ 688 uint32_t frame_len = 0; /* frame planner length */ 689 int buffer_num = 4; /* number of buffers for display */ 690 const char *pmem_region; 691 uint8_t num_planes = 0; 692 uint32_t planes[VIDEO_MAX_PLANES]; 693 694 cam_ctrl_dimension_t dim; 695 696 ALOGV("%s:BEGIN",__func__); 697 memset(&mHalCamCtrl->mMetadata, 0, sizeof(camera_frame_metadata_t)); 698 mHalCamCtrl->mPreviewMemoryLock.lock(); 699 memset(&mHalCamCtrl->mNoDispPreviewMemory, 0, sizeof(mHalCamCtrl->mNoDispPreviewMemory)); 700 mHalCamCtrl->mPreviewMemoryLock.unlock(); 701 memset(&mNotifyBuffer, 0, sizeof(mNotifyBuffer)); 702 703 /* get preview size, by qury mm_camera*/ 704 memset(&dim, 0, sizeof(cam_ctrl_dimension_t)); 705 ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION, &dim); 706 if (MM_CAMERA_OK != ret) { 707 ALOGE("%s: error - can't get camera dimension!", __func__); 708 ALOGV("%s: X", __func__); 709 return BAD_VALUE; 710 }else { 711 width = dim.display_width; 712 height = dim.display_height; 713 } 714 715 ret = getBufferNoDisplay( ); 716 if(ret != NO_ERROR) { 717 ALOGE("%s: cannot get memory from surface texture client, ret = %d", __func__, ret); 718 return ret; 719 } 720 721 /* set 4 buffers for display */ 722 memset(&mDisplayStreamBuf, 0, sizeof(mDisplayStreamBuf)); 723 mHalCamCtrl->mPreviewMemoryLock.lock(); 724 this->mDisplayStreamBuf.num = mHalCamCtrl->mNoDispPreviewMemory.buffer_count; 725 this->myMode=myMode; /*Need to assign this in constructor after translating from mask*/ 726 num_planes = dim.display_frame_offset.num_planes; 727 for (int i = 0; i < num_planes; i++) { 728 planes[i] = dim.display_frame_offset.mp[i].len; 729 } 730 this->mDisplayStreamBuf.frame_len = dim.display_frame_offset.frame_len; 731 732 memset(&mDisplayBuf, 0, sizeof(mDisplayBuf)); 733 mDisplayBuf.preview.buf.mp = new mm_camera_mp_buf_t[mDisplayStreamBuf.num]; 734 if (!mDisplayBuf.preview.buf.mp) { 735 ALOGE("%s Error allocating memory for mplanar struct ", __func__); 736 } 737 memset(mDisplayBuf.preview.buf.mp, 0, 738 mDisplayStreamBuf.num * sizeof(mm_camera_mp_buf_t)); 739 740 /*allocate memory for the buffers*/ 741 void *vaddr = NULL; 742 for(int i = 0; i < mDisplayStreamBuf.num; i++){ 743 if (mHalCamCtrl->mNoDispPreviewMemory.camera_memory[i] == NULL) 744 continue; 745 mDisplayStreamBuf.frame[i].fd = mHalCamCtrl->mNoDispPreviewMemory.fd[i]; 746 mDisplayStreamBuf.frame[i].cbcr_off = planes[0]; 747 mDisplayStreamBuf.frame[i].y_off = 0; 748 mDisplayStreamBuf.frame[i].path = OUTPUT_TYPE_P; 749 mDisplayStreamBuf.frame[i].buffer = 750 (long unsigned int)mHalCamCtrl->mNoDispPreviewMemory.camera_memory[i]->data; 751 mDisplayStreamBuf.frame[i].ion_dev_fd = mHalCamCtrl->mNoDispPreviewMemory.main_ion_fd[i]; 752 mDisplayStreamBuf.frame[i].fd_data = mHalCamCtrl->mNoDispPreviewMemory.ion_info_fd[i]; 753 754 ALOGV("%s: idx = %d, fd = %d, size = %d, cbcr_offset = %d, y_offset = %d, " 755 "vaddr = 0x%x", __func__, i, mDisplayStreamBuf.frame[i].fd, 756 frame_len, 757 mDisplayStreamBuf.frame[i].cbcr_off, mDisplayStreamBuf.frame[i].y_off, 758 (uint32_t)mDisplayStreamBuf.frame[i].buffer); 759 760 if (NO_ERROR != mHalCamCtrl->sendMappingBuf( 761 MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW, 762 i, 763 mDisplayStreamBuf.frame[i].fd, 764 mHalCamCtrl->mNoDispPreviewMemory.size, 765 mCameraId, CAM_SOCK_MSG_TYPE_FD_MAPPING)) { 766 ALOGE("%s: sending mapping data Msg Failed", __func__); 767 } 768 769 if(mHalCamCtrl->isZSLMode()) { 770 if (NO_ERROR != mHalCamCtrl->sendMappingBuf( 771 MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL, 772 i, 773 mDisplayStreamBuf.frame[i].fd, 774 mHalCamCtrl->mNoDispPreviewMemory.size, 775 mCameraId, CAM_SOCK_MSG_TYPE_FD_MAPPING)) { 776 ALOGE("%s: sending mapping data Msg Failed", __func__); 777 } 778 } 779 mDisplayBuf.preview.buf.mp[i].frame = mDisplayStreamBuf.frame[i]; 780 mDisplayBuf.preview.buf.mp[i].frame_offset = mDisplayStreamBuf.frame[i].y_off; 781 mDisplayBuf.preview.buf.mp[i].num_planes = num_planes; 782 783 /* Plane 0 needs to be set seperately. Set other planes 784 * in a loop. */ 785 mDisplayBuf.preview.buf.mp[i].planes[0].length = planes[0]; 786 mDisplayBuf.preview.buf.mp[i].planes[0].m.userptr = mDisplayStreamBuf.frame[i].fd; 787 mDisplayBuf.preview.buf.mp[i].planes[0].data_offset = 0; 788 mDisplayBuf.preview.buf.mp[i].planes[0].reserved[0] = 789 mDisplayBuf.preview.buf.mp[i].frame_offset; 790 for (int j = 1; j < num_planes; j++) { 791 mDisplayBuf.preview.buf.mp[i].planes[j].length = planes[j]; 792 mDisplayBuf.preview.buf.mp[i].planes[j].m.userptr = 793 mDisplayStreamBuf.frame[i].fd; 794 mDisplayBuf.preview.buf.mp[i].planes[j].data_offset = 0; 795 mDisplayBuf.preview.buf.mp[i].planes[j].reserved[0] = 796 mDisplayBuf.preview.buf.mp[i].planes[j-1].reserved[0] + 797 mDisplayBuf.preview.buf.mp[i].planes[j-1].length; 798 } 799 800 for (int j = 0; j < num_planes; j++) 801 ALOGV("Planes: %d length: %d userptr: %lu offset: %d\n", j, 802 mDisplayBuf.preview.buf.mp[i].planes[j].length, 803 mDisplayBuf.preview.buf.mp[i].planes[j].m.userptr, 804 mDisplayBuf.preview.buf.mp[i].planes[j].reserved[0]); 805 }/*end of for loop*/ 806 807 /* register the streaming buffers for the channel*/ 808 mDisplayBuf.ch_type = MM_CAMERA_CH_PREVIEW; 809 mDisplayBuf.preview.num = mDisplayStreamBuf.num; 810 mHalCamCtrl->mPreviewMemoryLock.unlock(); 811 ALOGV("%s:END",__func__); 812 return NO_ERROR; 813 814 end: 815 if (MM_CAMERA_OK == ret ) { 816 ALOGV("%s: X - NO_ERROR ", __func__); 817 return NO_ERROR; 818 } 819 820 ALOGV("%s: out of memory clean up", __func__); 821 /* release the allocated memory */ 822 823 ALOGV("%s: X - BAD_VALUE ", __func__); 824 return BAD_VALUE; 825 } 826 827 828 void QCameraStream_preview::dumpFrameToFile(struct msm_frame* newFrame) 829 { 830 #if 0 831 int32_t enabled = 0; 832 int frm_num; 833 uint32_t skip_mode; 834 char value[PROPERTY_VALUE_MAX]; 835 char buf[32]; 836 int w, h; 837 static int count = 0; 838 cam_ctrl_dimension_t dim; 839 int file_fd; 840 int rc = 0; 841 int len; 842 unsigned long addr; 843 unsigned long * tmp = (unsigned long *)newFrame->buffer; 844 addr = *tmp; 845 status_t ret = cam_config_get_parm(mHalCamCtrl->mCameraId, 846 MM_CAMERA_PARM_DIMENSION, &dim); 847 848 w = dim.display_width; 849 h = dim.display_height; 850 len = (w * h)*3/2; 851 count++; 852 if(count < 100) { 853 snprintf(buf, sizeof(buf), "/data/mzhu%d.yuv", count); 854 file_fd = open(buf, O_RDWR | O_CREAT, 0777); 855 856 rc = write(file_fd, (const void *)addr, len); 857 ALOGV("%s: file='%s', vaddr_old=0x%x, addr_map = 0x%p, len = %d, rc = %d", 858 __func__, buf, (uint32_t)newFrame->buffer, (void *)addr, len, rc); 859 close(file_fd); 860 ALOGV("%s: dump %s, rc = %d, len = %d", __func__, buf, rc, len); 861 } 862 #endif 863 } 864 865 status_t QCameraStream_preview::processPreviewFrameWithDisplay( 866 mm_camera_ch_data_buf_t *frame) 867 { 868 ALOGV("%s",__func__); 869 int err = 0; 870 int msgType = 0; 871 int i; 872 camera_memory_t *data = NULL; 873 camera_frame_metadata_t *metadata = NULL; 874 875 Mutex::Autolock lock(mStopCallbackLock); 876 if(!mActive) { 877 ALOGV("Preview Stopped. Returning callback"); 878 return NO_ERROR; 879 } 880 881 if(mHalCamCtrl==NULL) { 882 ALOGE("%s: X: HAL control object not set",__func__); 883 /*Call buf done*/ 884 return BAD_VALUE; 885 } 886 887 if(mHalCamCtrl->mPauseFramedispatch) { 888 if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId, frame)) { 889 ALOGE("BUF DONE FAILED for the recylce buffer"); 890 } 891 return NO_ERROR; 892 } 893 mHalCamCtrl->mCallbackLock.lock(); 894 camera_data_timestamp_callback rcb = mHalCamCtrl->mDataCbTimestamp; 895 void *rdata = mHalCamCtrl->mCallbackCookie; 896 mHalCamCtrl->mCallbackLock.unlock(); 897 nsecs_t timeStamp = seconds_to_nanoseconds(frame->def.frame->ts.tv_sec) ; 898 timeStamp += frame->def.frame->ts.tv_nsec; 899 900 if(mFirstFrameRcvd == false) { 901 mm_camera_util_profile("HAL: First preview frame received"); 902 mFirstFrameRcvd = true; 903 } 904 905 if (UNLIKELY(mHalCamCtrl->mDebugFps)) { 906 mHalCamCtrl->debugShowPreviewFPS(); 907 } 908 //dumpFrameToFile(frame->def.frame); 909 mHalCamCtrl->dumpFrameToFile(frame->def.frame, HAL_DUMP_FRM_PREVIEW); 910 911 mHalCamCtrl->mPreviewMemoryLock.lock(); 912 mNotifyBuffer[frame->def.idx] = *frame; 913 914 ALOGV("Enqueue buf handle %p\n", 915 mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]); 916 ALOGV("%s: camera call genlock_unlock", __FUNCTION__); 917 918 if (BUFFER_LOCKED == mHalCamCtrl->mPreviewMemory.local_flag[frame->def.idx]) { 919 ALOGV("%s: genlock_unlock_buffer hdl =%p", __FUNCTION__, (*mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx])); 920 if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t*) 921 (*mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]))) { 922 ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__); 923 //mHalCamCtrl->mPreviewMemoryLock.unlock(); 924 //return -EINVAL; 925 } else { 926 mHalCamCtrl->mPreviewMemory.local_flag[frame->def.idx] = BUFFER_UNLOCKED; 927 } 928 } else { 929 ALOGE("%s: buffer to be enqueued is not locked", __FUNCTION__); 930 mHalCamCtrl->mPreviewMemoryLock.unlock(); 931 return -EINVAL; 932 } 933 934 #ifdef USE_ION 935 struct ion_flush_data cache_inv_data; 936 int ion_fd; 937 ion_fd = frame->def.frame->ion_dev_fd; 938 cache_inv_data.vaddr = (void *)frame->def.frame->buffer; 939 cache_inv_data.fd = frame->def.frame->fd; 940 cache_inv_data.handle = frame->def.frame->fd_data.handle; 941 cache_inv_data.length = frame->def.frame->ion_alloc.len; 942 943 if (mHalCamCtrl->cache_ops(ion_fd, &cache_inv_data, 944 ION_IOC_CLEAN_INV_CACHES) < 0) 945 ALOGE("%s: Cache clean for Preview buffer %p fd = %d failed", __func__, 946 cache_inv_data.vaddr, cache_inv_data.fd); 947 #endif 948 949 if(mHFRFrameSkip == 1) 950 { 951 const char *str = mHalCamCtrl->mParameters.get( 952 QCameraParameters::KEY_VIDEO_HIGH_FRAME_RATE); 953 if(str != NULL){ 954 int is_hfr_off = 0; 955 mHFRFrameCnt++; 956 if(!strcmp(str, QCameraParameters::VIDEO_HFR_OFF)) { 957 is_hfr_off = 1; 958 err = this->mPreviewWindow->enqueue_buffer(this->mPreviewWindow, 959 (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]); 960 } else if (!strcmp(str, QCameraParameters::VIDEO_HFR_2X)) { 961 mHFRFrameCnt %= 2; 962 } else if (!strcmp(str, QCameraParameters::VIDEO_HFR_3X)) { 963 mHFRFrameCnt %= 3; 964 } else if (!strcmp(str, QCameraParameters::VIDEO_HFR_4X)) { 965 mHFRFrameCnt %= 4; 966 } 967 if(mHFRFrameCnt == 0) 968 err = this->mPreviewWindow->enqueue_buffer(this->mPreviewWindow, 969 (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]); 970 else if(!is_hfr_off) 971 err = this->mPreviewWindow->cancel_buffer(this->mPreviewWindow, 972 (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]); 973 } else 974 err = this->mPreviewWindow->enqueue_buffer(this->mPreviewWindow, 975 (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]); 976 } else { 977 err = this->mPreviewWindow->enqueue_buffer(this->mPreviewWindow, 978 (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]); 979 } 980 if(err != 0) { 981 ALOGE("%s: enqueue_buffer failed, err = %d", __func__, err); 982 } else { 983 ALOGV("%s: enqueue_buffer hdl=%p", __func__, *mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]); 984 mHalCamCtrl->mPreviewMemory.local_flag[frame->def.idx] = BUFFER_NOT_OWNED; 985 } 986 buffer_handle_t *buffer_handle = NULL; 987 int tmp_stride = 0; 988 err = this->mPreviewWindow->dequeue_buffer(this->mPreviewWindow, 989 &buffer_handle, &tmp_stride); 990 if (err == NO_ERROR && buffer_handle != NULL) { 991 992 ALOGV("%s: dequed buf hdl =%p", __func__, *buffer_handle); 993 for(i = 0; i < mHalCamCtrl->mPreviewMemory.buffer_count; i++) { 994 if(mHalCamCtrl->mPreviewMemory.buffer_handle[i] == buffer_handle) { 995 mHalCamCtrl->mPreviewMemory.local_flag[i] = BUFFER_UNLOCKED; 996 break; 997 } 998 } 999 if (i < mHalCamCtrl->mPreviewMemory.buffer_count ) { 1000 err = this->mPreviewWindow->lock_buffer(this->mPreviewWindow, buffer_handle); 1001 ALOGV("%s: camera call genlock_lock: hdl =%p", __FUNCTION__, *buffer_handle); 1002 if (GENLOCK_FAILURE == genlock_lock_buffer((native_handle_t*)(*buffer_handle), GENLOCK_WRITE_LOCK, 1003 GENLOCK_MAX_TIMEOUT)) { 1004 ALOGE("%s: genlock_lock_buffer(WRITE) failed", __FUNCTION__); 1005 //mHalCamCtrl->mPreviewMemoryLock.unlock(); 1006 // return -EINVAL; 1007 } else { 1008 mHalCamCtrl->mPreviewMemory.local_flag[i] = BUFFER_LOCKED; 1009 1010 if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId, &mNotifyBuffer[i])) { 1011 ALOGE("BUF DONE FAILED"); 1012 } 1013 } 1014 } 1015 } else 1016 ALOGV("%s: error in dequeue_buffer, enqueue_buffer idx = %d, no free buffer now", __func__, frame->def.idx); 1017 1018 /* Save the last displayed frame. We'll be using it to fill the gap between 1019 when preview stops and postview start during snapshot.*/ 1020 mLastQueuedFrame = &(mDisplayStreamBuf.frame[frame->def.idx]); 1021 mHalCamCtrl->mPreviewMemoryLock.unlock(); 1022 1023 mHalCamCtrl->mCallbackLock.lock(); 1024 camera_data_callback pcb = mHalCamCtrl->mDataCb; 1025 mHalCamCtrl->mCallbackLock.unlock(); 1026 ALOGV("Message enabled = 0x%x", mHalCamCtrl->mMsgEnabled); 1027 1028 camera_memory_t *previewMem = NULL; 1029 1030 if (pcb != NULL) { 1031 ALOGV("%s: mMsgEnabled =0x%x, preview format =%d", __func__, 1032 mHalCamCtrl->mMsgEnabled, mHalCamCtrl->mPreviewFormat); 1033 //Sending preview callback if corresponding Msgs are enabled 1034 if(mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) { 1035 ALOGV("%s: PCB callback enabled", __func__); 1036 msgType |= CAMERA_MSG_PREVIEW_FRAME; 1037 int previewBufSize; 1038 /* The preview buffer size sent back in the callback should be (width*height*bytes_per_pixel) 1039 * As all preview formats we support, use 12 bits per pixel, buffer size = previewWidth * previewHeight * 3/2. 1040 * We need to put a check if some other formats are supported in future. (punits) */ 1041 if ((mHalCamCtrl->mPreviewFormat == CAMERA_YUV_420_NV21) || (mHalCamCtrl->mPreviewFormat == CAMERA_YUV_420_NV12) || 1042 (mHalCamCtrl->mPreviewFormat == CAMERA_YUV_420_YV12)) 1043 { 1044 if (mHalCamCtrl->mPreviewFormat == CAMERA_YUV_420_YV12) { 1045 previewBufSize = ((mHalCamCtrl->mPreviewWidth+15)/16) *16* mHalCamCtrl->mPreviewHeight + 1046 ((mHalCamCtrl->mPreviewWidth/2+15)/16)*16* mHalCamCtrl->mPreviewHeight; 1047 } else { 1048 previewBufSize = mHalCamCtrl->mPreviewWidth * mHalCamCtrl->mPreviewHeight * 3/2; 1049 } 1050 if(previewBufSize != mHalCamCtrl->mPreviewMemory.private_buffer_handle[frame->def.idx]->size) { 1051 previewMem = mHalCamCtrl->mGetMemory(mHalCamCtrl->mPreviewMemory.private_buffer_handle[frame->def.idx]->fd, 1052 previewBufSize, 1, mHalCamCtrl->mCallbackCookie); 1053 if (!previewMem || !previewMem->data) { 1054 ALOGE("%s: mGetMemory failed.\n", __func__); 1055 } else { 1056 data = previewMem; 1057 } 1058 } else 1059 data = mHalCamCtrl->mPreviewMemory.camera_memory[frame->def.idx]; 1060 } else { 1061 data = mHalCamCtrl->mPreviewMemory.camera_memory[frame->def.idx]; 1062 ALOGE("Invalid preview format, buffer size in preview callback may be wrong."); 1063 } 1064 } else { 1065 data = NULL; 1066 } 1067 if(msgType) { 1068 mStopCallbackLock.unlock(); 1069 if(mActive) 1070 pcb(msgType, data, 0, metadata, mHalCamCtrl->mCallbackCookie); 1071 if (previewMem) 1072 previewMem->release(previewMem); 1073 mStopCallbackLock.lock(); 1074 } 1075 ALOGV("end of cb"); 1076 } else { 1077 ALOGV("%s PCB is not enabled", __func__); 1078 } 1079 if(rcb != NULL && mVFEOutputs == 1) 1080 { 1081 int flagwait = 1; 1082 if(mHalCamCtrl->mStartRecording == true && 1083 ( mHalCamCtrl->mMsgEnabled & CAMERA_MSG_VIDEO_FRAME)) 1084 { 1085 if (mHalCamCtrl->mStoreMetaDataInFrame) 1086 { 1087 if(mHalCamCtrl->mRecordingMemory.metadata_memory[frame->def.idx]) 1088 { 1089 flagwait = 1; 1090 mStopCallbackLock.unlock(); 1091 rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME, 1092 mHalCamCtrl->mRecordingMemory.metadata_memory[frame->def.idx], 1093 0, mHalCamCtrl->mCallbackCookie); 1094 mStopCallbackLock.lock(); 1095 }else 1096 flagwait = 0; 1097 } 1098 else 1099 { 1100 mStopCallbackLock.unlock(); 1101 rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME, 1102 mHalCamCtrl->mPreviewMemory.camera_memory[frame->def.idx], 1103 0, mHalCamCtrl->mCallbackCookie); 1104 mStopCallbackLock.lock(); 1105 } 1106 1107 if(flagwait){ 1108 Mutex::Autolock rLock(&mHalCamCtrl->mRecordFrameLock); 1109 if (mHalCamCtrl->mReleasedRecordingFrame != true) { 1110 mHalCamCtrl->mRecordWait.wait(mHalCamCtrl->mRecordFrameLock); 1111 } 1112 mHalCamCtrl->mReleasedRecordingFrame = false; 1113 } 1114 } 1115 } 1116 /* Save the last displayed frame. We'll be using it to fill the gap between 1117 when preview stops and postview start during snapshot.*/ 1118 //mLastQueuedFrame = frame->def.frame; 1119 /* 1120 if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId, frame)) 1121 { 1122 ALOGE("BUF DONE FAILED"); 1123 return BAD_VALUE; 1124 } 1125 */ 1126 return NO_ERROR; 1127 } 1128 1129 1130 status_t QCameraStream_preview::processPreviewFrameWithOutDisplay( 1131 mm_camera_ch_data_buf_t *frame) 1132 { 1133 ALOGV("%s",__func__); 1134 int err = 0; 1135 int msgType = 0; 1136 int i; 1137 camera_memory_t *data = NULL; 1138 camera_frame_metadata_t *metadata = NULL; 1139 1140 Mutex::Autolock lock(mStopCallbackLock); 1141 if(!mActive) { 1142 ALOGV("Preview Stopped. Returning callback"); 1143 return NO_ERROR; 1144 } 1145 if(mHalCamCtrl==NULL) { 1146 ALOGE("%s: X: HAL control object not set",__func__); 1147 /*Call buf done*/ 1148 return BAD_VALUE; 1149 } 1150 1151 if (UNLIKELY(mHalCamCtrl->mDebugFps)) { 1152 mHalCamCtrl->debugShowPreviewFPS(); 1153 } 1154 //dumpFrameToFile(frame->def.frame); 1155 mHalCamCtrl->dumpFrameToFile(frame->def.frame, HAL_DUMP_FRM_PREVIEW); 1156 1157 mHalCamCtrl->mPreviewMemoryLock.lock(); 1158 mNotifyBuffer[frame->def.idx] = *frame; 1159 1160 /* Save the last displayed frame. We'll be using it to fill the gap between 1161 when preview stops and postview start during snapshot.*/ 1162 mLastQueuedFrame = &(mDisplayStreamBuf.frame[frame->def.idx]); 1163 mHalCamCtrl->mPreviewMemoryLock.unlock(); 1164 1165 mHalCamCtrl->mCallbackLock.lock(); 1166 camera_data_callback pcb = mHalCamCtrl->mDataCb; 1167 mHalCamCtrl->mCallbackLock.unlock(); 1168 ALOGV("Message enabled = 0x%x", mHalCamCtrl->mMsgEnabled); 1169 1170 camera_memory_t *previewMem = NULL; 1171 int previewWidth, previewHeight; 1172 mHalCamCtrl->mParameters.getPreviewSize(&previewWidth, &previewHeight); 1173 1174 #ifdef USE_ION 1175 struct ion_flush_data cache_inv_data; 1176 int ion_fd; 1177 ion_fd = frame->def.frame->ion_dev_fd; 1178 cache_inv_data.vaddr = (void *)frame->def.frame->buffer; 1179 cache_inv_data.fd = frame->def.frame->fd; 1180 cache_inv_data.handle = frame->def.frame->fd_data.handle; 1181 cache_inv_data.length = frame->def.frame->ion_alloc.len; 1182 1183 if (mHalCamCtrl->cache_ops(ion_fd, &cache_inv_data, 1184 ION_IOC_CLEAN_INV_CACHES) < 0) 1185 ALOGE("%s: Cache clean for Preview buffer %p fd = %d failed", __func__, 1186 cache_inv_data.vaddr, cache_inv_data.fd); 1187 #endif 1188 1189 if (pcb != NULL) { 1190 //Sending preview callback if corresponding Msgs are enabled 1191 if(mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) { 1192 msgType |= CAMERA_MSG_PREVIEW_FRAME; 1193 int previewBufSize; 1194 /* For CTS : Forcing preview memory buffer lenth to be 1195 'previewWidth * previewHeight * 3/2'. 1196 Needed when gralloc allocated extra memory.*/ 1197 //Can add this check for other formats as well. 1198 if( mHalCamCtrl->mPreviewFormat == CAMERA_YUV_420_NV21) { 1199 previewBufSize = previewWidth * previewHeight * 3/2; 1200 if(previewBufSize != mHalCamCtrl->mPreviewMemory.private_buffer_handle[frame->def.idx]->size) { 1201 previewMem = mHalCamCtrl->mGetMemory(mHalCamCtrl->mPreviewMemory.private_buffer_handle[frame->def.idx]->fd, 1202 previewBufSize, 1, mHalCamCtrl->mCallbackCookie); 1203 if (!previewMem || !previewMem->data) { 1204 ALOGE("%s: mGetMemory failed.\n", __func__); 1205 } else { 1206 data = previewMem; 1207 } 1208 } else 1209 data = mHalCamCtrl->mPreviewMemory.camera_memory[frame->def.idx];//mPreviewHeap->mBuffers[frame->def.idx]; 1210 } else 1211 data = mHalCamCtrl->mPreviewMemory.camera_memory[frame->def.idx];//mPreviewHeap->mBuffers[frame->def.idx]; 1212 } else { 1213 data = NULL; 1214 } 1215 1216 if(mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_METADATA){ 1217 msgType |= CAMERA_MSG_PREVIEW_METADATA; 1218 metadata = &mHalCamCtrl->mMetadata; 1219 } else { 1220 metadata = NULL; 1221 } 1222 if(msgType) { 1223 mStopCallbackLock.unlock(); 1224 if(mActive) 1225 pcb(msgType, data, 0, metadata, mHalCamCtrl->mCallbackCookie); 1226 if (previewMem) 1227 previewMem->release(previewMem); 1228 mStopCallbackLock.lock(); 1229 } 1230 1231 if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId, &mNotifyBuffer[frame->def.idx])) { 1232 ALOGE("BUF DONE FAILED"); 1233 } 1234 1235 ALOGV("end of cb"); 1236 } 1237 1238 return NO_ERROR; 1239 } 1240 1241 status_t QCameraStream_preview::processPreviewFrame ( 1242 mm_camera_ch_data_buf_t *frame) 1243 { 1244 if (mHalCamCtrl->isNoDisplayMode()) { 1245 return processPreviewFrameWithOutDisplay(frame); 1246 } else { 1247 return processPreviewFrameWithDisplay(frame); 1248 } 1249 } 1250 1251 // --------------------------------------------------------------------------- 1252 // QCameraStream_preview 1253 // --------------------------------------------------------------------------- 1254 1255 QCameraStream_preview:: 1256 QCameraStream_preview(int cameraId, camera_mode_t mode) 1257 : QCameraStream(cameraId,mode), 1258 mLastQueuedFrame(NULL), 1259 mNumFDRcvd(0), 1260 mFirstFrameRcvd(false) 1261 { 1262 mHalCamCtrl = NULL; 1263 ALOGV("%s: E", __func__); 1264 ALOGV("%s: X", __func__); 1265 } 1266 // --------------------------------------------------------------------------- 1267 // QCameraStream_preview 1268 // --------------------------------------------------------------------------- 1269 1270 QCameraStream_preview::~QCameraStream_preview() { 1271 ALOGV("%s: E", __func__); 1272 if(mActive) { 1273 stop(); 1274 } 1275 if(mInit) { 1276 release(); 1277 } 1278 mInit = false; 1279 mActive = false; 1280 ALOGV("%s: X", __func__); 1281 1282 } 1283 // --------------------------------------------------------------------------- 1284 // QCameraStream_preview 1285 // --------------------------------------------------------------------------- 1286 1287 status_t QCameraStream_preview::init() { 1288 1289 status_t ret = NO_ERROR; 1290 ALOGV("%s: E", __func__); 1291 1292 ret = QCameraStream::initChannel (mCameraId, MM_CAMERA_CH_PREVIEW_MASK); 1293 if (NO_ERROR!=ret) { 1294 ALOGE("%s E: can't init native cammera preview ch\n",__func__); 1295 return ret; 1296 } 1297 1298 /* register a notify into the mmmm_camera_t object*/ 1299 (void) cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_PREVIEW, 1300 preview_notify_cb, 1301 MM_CAMERA_REG_BUF_CB_INFINITE, 1302 0,this); 1303 ALOGV("Debug : %s : cam_evt_register_buf_notify",__func__); 1304 buffer_handle_t *buffer_handle = NULL; 1305 int tmp_stride = 0; 1306 mInit = true; 1307 return ret; 1308 } 1309 // --------------------------------------------------------------------------- 1310 // QCameraStream_preview 1311 // --------------------------------------------------------------------------- 1312 1313 status_t QCameraStream_preview::start() 1314 { 1315 ALOGV("%s: E", __func__); 1316 status_t ret = NO_ERROR; 1317 cam_format_t previewFmt; 1318 Mutex::Autolock lock(mStopCallbackLock); 1319 1320 /* call start() in parent class to start the monitor thread*/ 1321 //QCameraStream::start (); 1322 previewFmt = mHalCamCtrl->getPreviewFormat(); 1323 setFormat(MM_CAMERA_CH_PREVIEW_MASK, previewFmt); 1324 1325 if (mHalCamCtrl->isNoDisplayMode()) { 1326 if(NO_ERROR!=initPreviewOnlyBuffers()){ 1327 return BAD_VALUE; 1328 } 1329 } else { 1330 if(NO_ERROR!=initDisplayBuffers()){ 1331 return BAD_VALUE; 1332 } 1333 } 1334 ALOGV("Debug : %s : initDisplayBuffers",__func__); 1335 1336 ret = cam_config_prepare_buf(mCameraId, &mDisplayBuf); 1337 ALOGV("Debug : %s : cam_config_prepare_buf",__func__); 1338 if(ret != MM_CAMERA_OK) { 1339 ALOGV("%s:reg preview buf err=%d\n", __func__, ret); 1340 ret = BAD_VALUE; 1341 goto error; 1342 }else { 1343 ret = NO_ERROR; 1344 } 1345 1346 /* For preview, the OP_MODE we set is dependent upon whether we are 1347 starting camera or camcorder. For snapshot, anyway we disable preview. 1348 However, for ZSL we need to set OP_MODE to OP_MODE_ZSL and not 1349 OP_MODE_VIDEO. We'll set that for now in CamCtrl. So in case of 1350 ZSL we skip setting Mode here */ 1351 1352 if (!(myMode & CAMERA_ZSL_MODE)) { 1353 ALOGV("Setting OP MODE to MM_CAMERA_OP_MODE_VIDEO"); 1354 mm_camera_op_mode_type_t op_mode=MM_CAMERA_OP_MODE_VIDEO; 1355 ret = cam_config_set_parm (mCameraId, MM_CAMERA_PARM_OP_MODE, 1356 &op_mode); 1357 ALOGV("OP Mode Set"); 1358 1359 if(MM_CAMERA_OK != ret) { 1360 ALOGE("%s: X :set mode MM_CAMERA_OP_MODE_VIDEO err=%d\n", __func__, ret); 1361 ret = BAD_VALUE; 1362 goto error; 1363 } 1364 }else { 1365 ALOGV("Setting OP MODE to MM_CAMERA_OP_MODE_ZSL"); 1366 mm_camera_op_mode_type_t op_mode=MM_CAMERA_OP_MODE_ZSL; 1367 ret = cam_config_set_parm (mCameraId, MM_CAMERA_PARM_OP_MODE, 1368 &op_mode); 1369 if(MM_CAMERA_OK != ret) { 1370 ALOGE("%s: X :set mode MM_CAMERA_OP_MODE_ZSL err=%d\n", __func__, ret); 1371 ret = BAD_VALUE; 1372 goto error; 1373 } 1374 } 1375 1376 /* call mm_camera action start(...) */ 1377 ALOGV("Starting Preview/Video Stream. "); 1378 mFirstFrameRcvd = false; 1379 ret = cam_ops_action(mCameraId, true, MM_CAMERA_OPS_PREVIEW, 0); 1380 1381 if (MM_CAMERA_OK != ret) { 1382 ALOGE ("%s: preview streaming start err=%d\n", __func__, ret); 1383 ret = BAD_VALUE; 1384 goto error; 1385 } 1386 1387 ALOGV("Debug : %s : Preview streaming Started",__func__); 1388 ret = NO_ERROR; 1389 1390 mActive = true; 1391 goto end; 1392 1393 error: 1394 putBufferToSurface(); 1395 end: 1396 ALOGV("%s: X", __func__); 1397 return ret; 1398 } 1399 1400 1401 // --------------------------------------------------------------------------- 1402 // QCameraStream_preview 1403 // --------------------------------------------------------------------------- 1404 void QCameraStream_preview::stop() { 1405 ALOGV("%s: E", __func__); 1406 int ret=MM_CAMERA_OK; 1407 1408 if(!mActive) { 1409 return; 1410 } 1411 Mutex::Autolock lock(mStopCallbackLock); 1412 mActive = false; 1413 /* unregister the notify fn from the mmmm_camera_t object*/ 1414 1415 ALOGV("%s: Stop the thread \n", __func__); 1416 /* call stop() in parent class to stop the monitor thread*/ 1417 ret = cam_ops_action(mCameraId, false, MM_CAMERA_OPS_PREVIEW, 0); 1418 if(MM_CAMERA_OK != ret) { 1419 ALOGE ("%s: camera preview stop err=%d\n", __func__, ret); 1420 } 1421 ret = cam_config_unprepare_buf(mCameraId, MM_CAMERA_CH_PREVIEW); 1422 if(ret != MM_CAMERA_OK) { 1423 ALOGE("%s:Unreg preview buf err=%d\n", __func__, ret); 1424 //ret = BAD_VALUE; 1425 } 1426 1427 /* In case of a clean stop, we need to clean all buffers*/ 1428 ALOGV("Debug : %s : Buffer Unprepared",__func__); 1429 /*free camera_memory handles and return buffer back to surface*/ 1430 if (! mHalCamCtrl->isNoDisplayMode() ) { 1431 putBufferToSurface(); 1432 } else { 1433 freeBufferNoDisplay( ); 1434 } 1435 1436 ALOGV("%s: X", __func__); 1437 1438 } 1439 // --------------------------------------------------------------------------- 1440 // QCameraStream_preview 1441 // --------------------------------------------------------------------------- 1442 void QCameraStream_preview::release() { 1443 1444 ALOGV("%s : BEGIN",__func__); 1445 int ret=MM_CAMERA_OK,i; 1446 1447 if(!mInit) 1448 { 1449 ALOGE("%s : Stream not Initalized",__func__); 1450 return; 1451 } 1452 1453 if(mActive) { 1454 this->stop(); 1455 } 1456 1457 ret= QCameraStream::deinitChannel(mCameraId, MM_CAMERA_CH_PREVIEW); 1458 ALOGV("Debug : %s : De init Channel",__func__); 1459 if(ret != MM_CAMERA_OK) { 1460 ALOGE("%s:Deinit preview channel failed=%d\n", __func__, ret); 1461 //ret = BAD_VALUE; 1462 } 1463 1464 (void)cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_PREVIEW, 1465 NULL, 1466 (mm_camera_register_buf_cb_type_t)NULL, 1467 NULL, 1468 NULL); 1469 mInit = false; 1470 ALOGV("%s: END", __func__); 1471 1472 } 1473 1474 QCameraStream* 1475 QCameraStream_preview::createInstance(int cameraId, 1476 camera_mode_t mode) 1477 { 1478 QCameraStream* pme = new QCameraStream_preview(cameraId, mode); 1479 return pme; 1480 } 1481 // --------------------------------------------------------------------------- 1482 // QCameraStream_preview 1483 // --------------------------------------------------------------------------- 1484 1485 void QCameraStream_preview::deleteInstance(QCameraStream *p) 1486 { 1487 if (p){ 1488 ALOGV("%s: BEGIN", __func__); 1489 p->release(); 1490 delete p; 1491 p = NULL; 1492 ALOGV("%s: END", __func__); 1493 } 1494 } 1495 1496 1497 /* Temp helper function */ 1498 void *QCameraStream_preview::getLastQueuedFrame(void) 1499 { 1500 return mLastQueuedFrame; 1501 } 1502 1503 // --------------------------------------------------------------------------- 1504 // No code beyone this line 1505 // --------------------------------------------------------------------------- 1506 }; // namespace android 1507