1 /* 2 ** Copyright (c) 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 ALOG_NDEBUG 0 20 #define ALOG_NIDEBUG 0 21 #define LOG_TAG "QCameraHWI_Preview" 22 #include <utils/Log.h> 23 #include <utils/threads.h> 24 #include <fcntl.h> 25 #include <sys/mman.h> 26 27 #include "QCameraHAL.h" 28 #include "QCameraHWI.h" 29 #include <gralloc_priv.h> 30 #include <genlock.h> 31 32 #define UNLIKELY(exp) __builtin_expect(!!(exp), 0) 33 34 /* QCameraHWI_Preview class implementation goes here*/ 35 /* following code implement the preview mode's image capture & display logic of this class*/ 36 37 namespace android { 38 39 // --------------------------------------------------------------------------- 40 // Preview Callback 41 // --------------------------------------------------------------------------- 42 static void preview_notify_cb(mm_camera_ch_data_buf_t *frame, 43 void *user_data) 44 { 45 QCameraStream_preview *pme = (QCameraStream_preview *)user_data; 46 mm_camera_ch_data_buf_t *bufs_used = 0; 47 ALOGV("%s: E", __func__); 48 /* for peview data, there is no queue, so directly use*/ 49 if(pme==NULL) { 50 ALOGE("%s: X : Incorrect cookie",__func__); 51 /*Call buf done*/ 52 return; 53 } 54 55 pme->processPreviewFrame(frame); 56 ALOGV("%s: X", __func__); 57 } 58 59 status_t QCameraStream_preview::setPreviewWindow(preview_stream_ops_t* window) 60 { 61 status_t retVal = NO_ERROR; 62 ALOGE(" %s: E ", __FUNCTION__); 63 if( window == NULL) { 64 ALOGW(" Setting NULL preview window "); 65 /* TODO: Current preview window will be invalidated. 66 * Release all the buffers back */ 67 // relinquishBuffers(); 68 } 69 mDisplayLock.lock(); 70 mPreviewWindow = window; 71 mDisplayLock.unlock(); 72 ALOGV(" %s : X ", __FUNCTION__ ); 73 return retVal; 74 } 75 76 status_t QCameraStream_preview::getBufferFromSurface() { 77 int err = 0; 78 int numMinUndequeuedBufs = 0; 79 int format = 0; 80 status_t ret = NO_ERROR; 81 82 ALOGI(" %s : E ", __FUNCTION__); 83 84 if( mPreviewWindow == NULL) { 85 ALOGE("%s: mPreviewWindow = NULL", __func__); 86 return INVALID_OPERATION; 87 } 88 cam_ctrl_dimension_t dim; 89 90 //mDisplayLock.lock(); 91 cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION,&dim); 92 93 format = mHalCamCtrl->getPreviewFormatInfo().Hal_format; 94 if(ret != NO_ERROR) { 95 ALOGE("%s: display format %d is not supported", __func__, dim.prev_format); 96 goto end; 97 } 98 numMinUndequeuedBufs = 0; 99 if(mPreviewWindow->get_min_undequeued_buffer_count) { 100 err = mPreviewWindow->get_min_undequeued_buffer_count(mPreviewWindow, &numMinUndequeuedBufs); 101 if (err != 0) { 102 ALOGE("get_min_undequeued_buffer_count failed: %s (%d)", 103 strerror(-err), -err); 104 ret = UNKNOWN_ERROR; 105 goto end; 106 } 107 } 108 mHalCamCtrl->mPreviewMemoryLock.lock(); 109 mHalCamCtrl->mPreviewMemory.buffer_count = kPreviewBufferCount + numMinUndequeuedBufs;; 110 err = mPreviewWindow->set_buffer_count(mPreviewWindow, mHalCamCtrl->mPreviewMemory.buffer_count ); 111 if (err != 0) { 112 ALOGE("set_buffer_count failed: %s (%d)", 113 strerror(-err), -err); 114 ret = UNKNOWN_ERROR; 115 goto end; 116 } 117 err = mPreviewWindow->set_buffers_geometry(mPreviewWindow, 118 dim.display_width, dim.display_height, format); 119 if (err != 0) { 120 ALOGE("set_buffers_geometry failed: %s (%d)", 121 strerror(-err), -err); 122 ret = UNKNOWN_ERROR; 123 goto end; 124 } 125 err = mPreviewWindow->set_usage(mPreviewWindow, 126 GRALLOC_USAGE_PRIVATE_ADSP_HEAP | 127 GRALLOC_USAGE_PRIVATE_UNCACHED); 128 if(err != 0) { 129 /* set_usage error out */ 130 ALOGE("%s: set_usage rc = %d", __func__, err); 131 ret = UNKNOWN_ERROR; 132 goto end; 133 } 134 for (int cnt = 0; cnt < mHalCamCtrl->mPreviewMemory.buffer_count; cnt++) { 135 int stride; 136 err = mPreviewWindow->dequeue_buffer(mPreviewWindow, 137 &mHalCamCtrl->mPreviewMemory.buffer_handle[cnt], 138 &mHalCamCtrl->mPreviewMemory.stride[cnt]); 139 if(!err) { 140 err = mPreviewWindow->lock_buffer(this->mPreviewWindow, 141 mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]); 142 143 // lock the buffer using genlock 144 ALOGD("%s: camera call genlock_lock", __FUNCTION__); 145 if (GENLOCK_NO_ERROR != genlock_lock_buffer((native_handle_t *)(*mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]), 146 GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) { 147 ALOGE("%s: genlock_lock_buffer(WRITE) failed", __FUNCTION__); 148 mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_UNLOCKED; 149 mHalCamCtrl->mPreviewMemoryLock.unlock(); 150 return -EINVAL; 151 } 152 mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_LOCKED; 153 } else 154 ALOGE("%s: dequeue_buffer idx = %d err = %d", __func__, cnt, err); 155 156 ALOGE("%s: dequeue buf: %u\n", __func__, (unsigned int)mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]); 157 158 if(err != 0) { 159 ALOGE("%s: dequeue_buffer failed: %s (%d)", __func__, 160 strerror(-err), -err); 161 ret = UNKNOWN_ERROR; 162 for(int i = 0; i < cnt; i++) { 163 ALOGD("%s: camera call genlock_unlock", __FUNCTION__); 164 if (BUFFER_LOCKED == mHalCamCtrl->mPreviewMemory.local_flag[i]) { 165 if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t *) 166 (*(mHalCamCtrl->mPreviewMemory.buffer_handle[i])))) { 167 ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__); 168 mHalCamCtrl->mPreviewMemoryLock.unlock(); 169 return -EINVAL; 170 } 171 } 172 err = mPreviewWindow->cancel_buffer(mPreviewWindow, 173 mHalCamCtrl->mPreviewMemory.buffer_handle[i]); 174 mHalCamCtrl->mPreviewMemory.buffer_handle[i] = NULL; 175 mHalCamCtrl->mPreviewMemory.local_flag[i] = BUFFER_UNLOCKED; 176 } 177 goto end; 178 } 179 mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt] = 180 (struct private_handle_t *)(*mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]); 181 mHalCamCtrl->mPreviewMemory.camera_memory[cnt] = 182 mHalCamCtrl->mGetMemory(mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->fd, 183 mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->size, 1, (void *)this); 184 ALOGE("%s: idx = %d, fd = %d, size = %d, offset = %d", __func__, 185 cnt, mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->fd, 186 mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->size, 187 mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->offset); 188 } 189 190 191 memset(&mHalCamCtrl->mMetadata, 0, sizeof(mHalCamCtrl->mMetadata)); 192 memset(mHalCamCtrl->mFace, 0, sizeof(mHalCamCtrl->mFace)); 193 194 ALOGI(" %s : X ",__FUNCTION__); 195 end: 196 //mDisplayLock.unlock(); 197 mHalCamCtrl->mPreviewMemoryLock.unlock(); 198 199 return NO_ERROR; 200 } 201 202 status_t QCameraStream_preview::putBufferToSurface() { 203 int err = 0; 204 status_t ret = NO_ERROR; 205 206 ALOGI(" %s : E ", __FUNCTION__); 207 208 //mDisplayLock.lock(); 209 mHalCamCtrl->mPreviewMemoryLock.lock(); 210 for (int cnt = 0; cnt < mHalCamCtrl->mPreviewMemory.buffer_count; cnt++) { 211 mHalCamCtrl->mPreviewMemory.camera_memory[cnt]->release(mHalCamCtrl->mPreviewMemory.camera_memory[cnt]); 212 if (BUFFER_LOCKED == mHalCamCtrl->mPreviewMemory.local_flag[cnt]) { 213 ALOGD("%s: camera call genlock_unlock", __FUNCTION__); 214 if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t *) 215 (*(mHalCamCtrl->mPreviewMemory.buffer_handle[cnt])))) { 216 ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__); 217 mHalCamCtrl->mPreviewMemoryLock.unlock(); 218 return -EINVAL; 219 } else { 220 mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_UNLOCKED; 221 } 222 } 223 err = mPreviewWindow->cancel_buffer(mPreviewWindow, mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]); 224 ALOGE(" put buffer %d successfully", cnt); 225 } 226 memset(&mHalCamCtrl->mPreviewMemory, 0, sizeof(mHalCamCtrl->mPreviewMemory)); 227 mHalCamCtrl->mPreviewMemoryLock.unlock(); 228 //mDisplayLock.unlock(); 229 ALOGI(" %s : X ",__FUNCTION__); 230 return NO_ERROR; 231 } 232 233 void QCameraStream_preview::notifyROIEvent(fd_roi_t roi) 234 { 235 switch (roi.type) { 236 case FD_ROI_TYPE_HEADER: 237 { 238 mDisplayLock.lock(); 239 mNumFDRcvd = 0; 240 memset(mHalCamCtrl->mFace, 0, sizeof(mHalCamCtrl->mFace)); 241 mHalCamCtrl->mMetadata.faces = mHalCamCtrl->mFace; 242 mHalCamCtrl->mMetadata.number_of_faces = roi.d.hdr.num_face_detected; 243 if(mHalCamCtrl->mMetadata.number_of_faces > MAX_ROI) 244 mHalCamCtrl->mMetadata.number_of_faces = MAX_ROI; 245 mDisplayLock.unlock(); 246 247 if (mHalCamCtrl->mMetadata.number_of_faces == 0) { 248 // Clear previous faces 249 mHalCamCtrl->mCallbackLock.lock(); 250 camera_data_callback pcb = mHalCamCtrl->mDataCb; 251 mHalCamCtrl->mCallbackLock.unlock(); 252 253 if (pcb && (mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_METADATA)){ 254 ALOGE("%s: Face detection RIO callback", __func__); 255 pcb(CAMERA_MSG_PREVIEW_METADATA, NULL, 0, &mHalCamCtrl->mMetadata, mHalCamCtrl->mCallbackCookie); 256 } 257 } 258 } 259 break; 260 case FD_ROI_TYPE_DATA: 261 { 262 mDisplayLock.lock(); 263 int idx = roi.d.data.idx; 264 if (idx >= mHalCamCtrl->mMetadata.number_of_faces) { 265 mDisplayLock.unlock(); 266 ALOGE("%s: idx %d out of boundary %d", __func__, idx, mHalCamCtrl->mMetadata.number_of_faces); 267 break; 268 } 269 270 mHalCamCtrl->mFace[idx].id = roi.d.data.face.id; 271 mHalCamCtrl->mFace[idx].score = roi.d.data.face.score / 10; // keep within range 0~100 272 273 // top 274 mHalCamCtrl->mFace[idx].rect[0] = 275 roi.d.data.face.face_boundary.x*2000/mHalCamCtrl->mDimension.display_width - 1000; 276 //right 277 mHalCamCtrl->mFace[idx].rect[1] = 278 roi.d.data.face.face_boundary.y*2000/mHalCamCtrl->mDimension.display_height - 1000; 279 //bottom 280 mHalCamCtrl->mFace[idx].rect[2] = mHalCamCtrl->mFace[idx].rect[0] + 281 roi.d.data.face.face_boundary.dx*2000/mHalCamCtrl->mDimension.display_width; 282 //left 283 mHalCamCtrl->mFace[idx].rect[3] = mHalCamCtrl->mFace[idx].rect[1] + 284 roi.d.data.face.face_boundary.dy*2000/mHalCamCtrl->mDimension.display_height; 285 286 // Center of left eye 287 mHalCamCtrl->mFace[idx].left_eye[0] = 288 roi.d.data.face.left_eye_center[0]*2000/mHalCamCtrl->mDimension.display_width - 1000; 289 mHalCamCtrl->mFace[idx].left_eye[1] = 290 roi.d.data.face.left_eye_center[1]*2000/mHalCamCtrl->mDimension.display_height - 1000; 291 292 // Center of right eye 293 mHalCamCtrl->mFace[idx].right_eye[0] = 294 roi.d.data.face.right_eye_center[0]*2000/mHalCamCtrl->mDimension.display_width - 1000; 295 mHalCamCtrl->mFace[idx].right_eye[1] = 296 roi.d.data.face.right_eye_center[1]*2000/mHalCamCtrl->mDimension.display_height - 1000; 297 298 // Center of mouth 299 mHalCamCtrl->mFace[idx].mouth[0] = 300 roi.d.data.face.mouth_center[0]*2000/mHalCamCtrl->mDimension.display_width - 1000; 301 mHalCamCtrl->mFace[idx].mouth[1] = 302 roi.d.data.face.mouth_center[1]*2000/mHalCamCtrl->mDimension.display_height - 1000; 303 304 mHalCamCtrl->mFace[idx].smile_degree = roi.d.data.face.smile_degree; 305 mHalCamCtrl->mFace[idx].smile_score = roi.d.data.face.smile_confidence; 306 mHalCamCtrl->mFace[idx].blink_detected = roi.d.data.face.blink_detected; 307 mHalCamCtrl->mFace[idx].face_recognised = roi.d.data.face.is_face_recognised; 308 mHalCamCtrl->mFace[idx].gaze_angle = roi.d.data.face.gaze_angle; 309 310 /* newly added */ 311 // upscale by 2 to recover from demaen downscaling 312 mHalCamCtrl->mFace[idx].updown_dir = roi.d.data.face.updown_dir*2; 313 mHalCamCtrl->mFace[idx].leftright_dir = roi.d.data.face.leftright_dir*2; 314 mHalCamCtrl->mFace[idx].roll_dir = roi.d.data.face.roll_dir*2; 315 316 mHalCamCtrl->mFace[idx].leye_blink = roi.d.data.face.left_blink; 317 mHalCamCtrl->mFace[idx].reye_blink = roi.d.data.face.right_blink; 318 mHalCamCtrl->mFace[idx].left_right_gaze = roi.d.data.face.left_right_gaze; 319 mHalCamCtrl->mFace[idx].top_bottom_gaze = roi.d.data.face.top_bottom_gaze; 320 321 ALOGE("%s: Face(%d, %d, %d, %d), leftEye(%d, %d), rightEye(%d, %d), mouth(%d, %d), smile(%d, %d), blinked(%d)", __func__, 322 mHalCamCtrl->mFace[idx].rect[0], mHalCamCtrl->mFace[idx].rect[1], 323 mHalCamCtrl->mFace[idx].rect[2], mHalCamCtrl->mFace[idx].rect[3], 324 mHalCamCtrl->mFace[idx].left_eye[0], mHalCamCtrl->mFace[idx].left_eye[1], 325 mHalCamCtrl->mFace[idx].right_eye[0], mHalCamCtrl->mFace[idx].right_eye[1], 326 mHalCamCtrl->mFace[idx].mouth[0], mHalCamCtrl->mFace[idx].mouth[1], 327 roi.d.data.face.smile_degree, roi.d.data.face.smile_confidence, roi.d.data.face.blink_detected); 328 329 mNumFDRcvd++; 330 mDisplayLock.unlock(); 331 332 if (mNumFDRcvd == mHalCamCtrl->mMetadata.number_of_faces) { 333 mHalCamCtrl->mCallbackLock.lock(); 334 camera_data_callback pcb = mHalCamCtrl->mDataCb; 335 mHalCamCtrl->mCallbackLock.unlock(); 336 337 if (pcb && (mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_METADATA)){ 338 ALOGE("%s: Face detection RIO callback with %d faces detected (score=%d)", __func__, mNumFDRcvd, mHalCamCtrl->mFace[idx].score); 339 pcb(CAMERA_MSG_PREVIEW_METADATA, NULL, 0, &mHalCamCtrl->mMetadata, mHalCamCtrl->mCallbackCookie); 340 } 341 } 342 } 343 break; 344 } 345 } 346 347 status_t QCameraStream_preview::initDisplayBuffers() 348 { 349 status_t ret = NO_ERROR; 350 int width = 0; /* width of channel */ 351 int height = 0; /* height of channel */ 352 uint32_t frame_len = 0; /* frame planner length */ 353 int buffer_num = 4; /* number of buffers for display */ 354 const char *pmem_region; 355 uint8_t num_planes = 0; 356 uint32_t planes[VIDEO_MAX_PLANES]; 357 358 cam_ctrl_dimension_t dim; 359 360 ALOGE("%s:BEGIN",__func__); 361 memset(&mHalCamCtrl->mMetadata, 0, sizeof(camera_frame_metadata_t)); 362 mHalCamCtrl->mPreviewMemoryLock.lock(); 363 memset(&mHalCamCtrl->mPreviewMemory, 0, sizeof(mHalCamCtrl->mPreviewMemory)); 364 mHalCamCtrl->mPreviewMemoryLock.unlock(); 365 memset(&mNotifyBuffer, 0, sizeof(mNotifyBuffer)); 366 367 /* get preview size, by qury mm_camera*/ 368 memset(&dim, 0, sizeof(cam_ctrl_dimension_t)); 369 370 memset(&(this->mDisplayStreamBuf),0, sizeof(this->mDisplayStreamBuf)); 371 372 ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION, &dim); 373 if (MM_CAMERA_OK != ret) { 374 ALOGE("%s: error - can't get camera dimension!", __func__); 375 ALOGE("%s: X", __func__); 376 return BAD_VALUE; 377 }else { 378 width = dim.display_width, 379 height = dim.display_height; 380 } 381 382 ret = getBufferFromSurface(); 383 if(ret != NO_ERROR) { 384 ALOGE("%s: cannot get memory from surface texture client, ret = %d", __func__, ret); 385 return ret; 386 } 387 388 /* set 4 buffers for display */ 389 memset(&mDisplayStreamBuf, 0, sizeof(mDisplayStreamBuf)); 390 mHalCamCtrl->mPreviewMemoryLock.lock(); 391 this->mDisplayStreamBuf.num = mHalCamCtrl->mPreviewMemory.buffer_count; 392 this->myMode=myMode; /*Need to assign this in constructor after translating from mask*/ 393 num_planes = 2; 394 planes[0] = dim.display_frame_offset.mp[0].len; 395 planes[1] = dim.display_frame_offset.mp[1].len; 396 this->mDisplayStreamBuf.frame_len = dim.display_frame_offset.frame_len; 397 398 mDisplayBuf.preview.buf.mp = new mm_camera_mp_buf_t[mDisplayStreamBuf.num]; 399 if (!mDisplayBuf.preview.buf.mp) { 400 ALOGE("%s Error allocating memory for mplanar struct ", __func__); 401 } 402 memset(mDisplayBuf.preview.buf.mp, 0, 403 mDisplayStreamBuf.num * sizeof(mm_camera_mp_buf_t)); 404 405 /*allocate memory for the buffers*/ 406 void *vaddr = NULL; 407 for(int i = 0; i < mDisplayStreamBuf.num; i++){ 408 if (mHalCamCtrl->mPreviewMemory.private_buffer_handle[i] == NULL) 409 continue; 410 mDisplayStreamBuf.frame[i].fd = mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->fd; 411 mDisplayStreamBuf.frame[i].cbcr_off = planes[0]; 412 mDisplayStreamBuf.frame[i].y_off = 0; 413 mDisplayStreamBuf.frame[i].path = OUTPUT_TYPE_P; 414 mHalCamCtrl->mPreviewMemory.addr_offset[i] = 415 mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->offset; 416 mDisplayStreamBuf.frame[i].buffer = 417 (long unsigned int)mHalCamCtrl->mPreviewMemory.camera_memory[i]->data; 418 419 ALOGE("%s: idx = %d, fd = %d, size = %d, cbcr_offset = %d, y_offset = %d, offset = %d, vaddr = 0x%x", 420 __func__, i, 421 mDisplayStreamBuf.frame[i].fd, 422 mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->size, 423 mDisplayStreamBuf.frame[i].cbcr_off, 424 mDisplayStreamBuf.frame[i].y_off, 425 mHalCamCtrl->mPreviewMemory.addr_offset[i], 426 (uint32_t)mDisplayStreamBuf.frame[i].buffer); 427 428 429 mDisplayBuf.preview.buf.mp[i].frame = mDisplayStreamBuf.frame[i]; 430 mDisplayBuf.preview.buf.mp[i].frame_offset = mHalCamCtrl->mPreviewMemory.addr_offset[i]; 431 mDisplayBuf.preview.buf.mp[i].num_planes = num_planes; 432 433 /* Plane 0 needs to be set seperately. Set other planes 434 * in a loop. */ 435 mDisplayBuf.preview.buf.mp[i].planes[0].length = planes[0]; 436 mDisplayBuf.preview.buf.mp[i].planes[0].m.userptr = mDisplayStreamBuf.frame[i].fd; 437 mDisplayBuf.preview.buf.mp[i].planes[0].data_offset = 0; 438 mDisplayBuf.preview.buf.mp[i].planes[0].reserved[0] = 439 mDisplayBuf.preview.buf.mp[i].frame_offset; 440 for (int j = 1; j < num_planes; j++) { 441 mDisplayBuf.preview.buf.mp[i].planes[j].length = planes[j]; 442 mDisplayBuf.preview.buf.mp[i].planes[j].m.userptr = 443 mDisplayStreamBuf.frame[i].fd; 444 mDisplayBuf.preview.buf.mp[i].planes[j].data_offset = 0; 445 mDisplayBuf.preview.buf.mp[i].planes[j].reserved[0] = 446 mDisplayBuf.preview.buf.mp[i].planes[j-1].reserved[0] + 447 mDisplayBuf.preview.buf.mp[i].planes[j-1].length; 448 } 449 450 for (int j = 0; j < num_planes; j++) { 451 ALOGE("Planes: %d length: %d userptr: %lu offset: %d\n", 452 j, mDisplayBuf.preview.buf.mp[i].planes[j].length, 453 mDisplayBuf.preview.buf.mp[i].planes[j].m.userptr, 454 mDisplayBuf.preview.buf.mp[i].planes[j].reserved[0]); 455 } 456 457 }/*end of for loop*/ 458 459 /* register the streaming buffers for the channel*/ 460 mDisplayBuf.ch_type = MM_CAMERA_CH_PREVIEW; 461 mDisplayBuf.preview.num = mDisplayStreamBuf.num; 462 mHalCamCtrl->mPreviewMemoryLock.unlock(); 463 ALOGE("%s:END",__func__); 464 return NO_ERROR; 465 466 end: 467 if (MM_CAMERA_OK == ret ) { 468 ALOGV("%s: X - NO_ERROR ", __func__); 469 return NO_ERROR; 470 } 471 472 ALOGV("%s: out of memory clean up", __func__); 473 /* release the allocated memory */ 474 475 ALOGV("%s: X - BAD_VALUE ", __func__); 476 return BAD_VALUE; 477 } 478 479 void QCameraStream_preview::dumpFrameToFile(struct msm_frame* newFrame) 480 { 481 int32_t enabled = 0; 482 int frm_num; 483 uint32_t skip_mode; 484 char value[PROPERTY_VALUE_MAX]; 485 char buf[32]; 486 int w, h; 487 static int count = 0; 488 cam_ctrl_dimension_t dim; 489 int file_fd; 490 int rc = 0; 491 int len; 492 unsigned long addr; 493 unsigned long * tmp = (unsigned long *)newFrame->buffer; 494 addr = *tmp; 495 status_t ret = cam_config_get_parm(mHalCamCtrl->mCameraId, 496 MM_CAMERA_PARM_DIMENSION, &dim); 497 498 w = dim.display_width; 499 h = dim.display_height; 500 len = (w * h)*3/2; 501 count++; 502 if(count < 100) { 503 snprintf(buf, sizeof(buf), "/data/mzhu%d.yuv", count); 504 file_fd = open(buf, O_RDWR | O_CREAT, 0777); 505 506 rc = write(file_fd, (const void *)addr, len); 507 ALOGE("%s: file='%s', vaddr_old=0x%x, addr_map = 0x%p, len = %d, rc = %d", 508 __func__, buf, (uint32_t)newFrame->buffer, (void *)addr, len, rc); 509 close(file_fd); 510 ALOGE("%s: dump %s, rc = %d, len = %d", __func__, buf, rc, len); 511 } 512 } 513 514 status_t QCameraStream_preview::processPreviewFrame(mm_camera_ch_data_buf_t *frame) 515 { 516 ALOGV("%s",__func__); 517 int err = 0; 518 int msgType = 0; 519 camera_memory_t *data = NULL; 520 camera_frame_metadata_t *metadata = NULL; 521 522 Mutex::Autolock lock(mStopCallbackLock); 523 if(!mActive) { 524 ALOGE("Preview Stopped. Returning callback"); 525 return NO_ERROR; 526 } 527 if(mHalCamCtrl==NULL) { 528 ALOGE("%s: X: HAL control object not set",__func__); 529 /*Call buf done*/ 530 return BAD_VALUE; 531 } 532 533 mHalCamCtrl->mCallbackLock.lock(); 534 camera_data_timestamp_callback rcb = mHalCamCtrl->mDataCbTimestamp; 535 void *rdata = mHalCamCtrl->mCallbackCookie; 536 mHalCamCtrl->mCallbackLock.unlock(); 537 538 if (UNLIKELY(mHalCamCtrl->mDebugFps)) { 539 mHalCamCtrl->debugShowPreviewFPS(); 540 } 541 //dumpFrameToFile(frame->def.frame); 542 mHalCamCtrl->dumpFrameToFile(frame->def.frame, HAL_DUMP_FRM_PREVIEW); 543 544 nsecs_t timeStamp = systemTime(); 545 546 mHalCamCtrl->mPreviewMemoryLock.lock(); 547 mNotifyBuffer[frame->def.idx] = *frame; 548 // mzhu fix me, need to check meta data also. 549 550 ALOGI("Enqueue buf handle %p\n", 551 mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]); 552 ALOGD("%s: camera call genlock_unlock", __FUNCTION__); 553 if (BUFFER_LOCKED == mHalCamCtrl->mPreviewMemory.local_flag[frame->def.idx]) { 554 if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t*) 555 (*mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]))) { 556 ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__); 557 mHalCamCtrl->mPreviewMemoryLock.unlock(); 558 return -EINVAL; 559 } else { 560 mHalCamCtrl->mPreviewMemory.local_flag[frame->def.idx] = BUFFER_UNLOCKED; 561 } 562 } else { 563 ALOGE("%s: buffer to be enqueued is not locked", __FUNCTION__); 564 mHalCamCtrl->mPreviewMemoryLock.unlock(); 565 return -EINVAL; 566 } 567 err = this->mPreviewWindow->enqueue_buffer(this->mPreviewWindow, 568 (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]); 569 if(err != 0) { 570 ALOGE("%s: enqueue_buffer failed, err = %d", __func__, err); 571 } 572 buffer_handle_t *buffer_handle = NULL; 573 int tmp_stride = 0; 574 err = this->mPreviewWindow->dequeue_buffer(this->mPreviewWindow, 575 &buffer_handle, &tmp_stride); 576 if (err == NO_ERROR && buffer_handle != NULL) { 577 err = this->mPreviewWindow->lock_buffer(this->mPreviewWindow, buffer_handle); 578 ALOGD("%s: camera call genlock_lock", __FUNCTION__); 579 if (GENLOCK_FAILURE == genlock_lock_buffer((native_handle_t*)(*buffer_handle), GENLOCK_WRITE_LOCK, 580 GENLOCK_MAX_TIMEOUT)) { 581 ALOGE("%s: genlock_lock_buffer(WRITE) failed", __FUNCTION__); 582 mHalCamCtrl->mPreviewMemoryLock.unlock(); 583 return -EINVAL; 584 } 585 for(int i = 0; i < mHalCamCtrl->mPreviewMemory.buffer_count; i++) { 586 ALOGD("h1: %p h2: %p\n", mHalCamCtrl->mPreviewMemory.buffer_handle[i], buffer_handle); 587 if(mHalCamCtrl->mPreviewMemory.buffer_handle[i] == buffer_handle) { 588 mm_camera_ch_data_buf_t tmp_frame; 589 mHalCamCtrl->mPreviewMemory.local_flag[i] = BUFFER_LOCKED; 590 if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId, &mNotifyBuffer[i])) { 591 ALOGD("BUF DONE FAILED"); 592 mHalCamCtrl->mPreviewMemoryLock.unlock(); 593 return BAD_VALUE; 594 } 595 break; 596 } 597 } 598 } else 599 ALOGE("%s: error in dequeue_buffer, enqueue_buffer idx = %d, no free buffer now", __func__, frame->def.idx); 600 /* Save the last displayed frame. We'll be using it to fill the gap between 601 when preview stops and postview start during snapshot.*/ 602 mLastQueuedFrame = &(mDisplayStreamBuf.frame[frame->def.idx]); 603 mHalCamCtrl->mPreviewMemoryLock.unlock(); 604 605 mHalCamCtrl->mCallbackLock.lock(); 606 camera_data_callback pcb = mHalCamCtrl->mDataCb; 607 mHalCamCtrl->mCallbackLock.unlock(); 608 ALOGD("Message enabled = 0x%x", mHalCamCtrl->mMsgEnabled); 609 610 if (pcb != NULL) { 611 //Sending preview callback if corresponding Msgs are enabled 612 if(mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) { 613 msgType |= CAMERA_MSG_PREVIEW_FRAME; 614 data = mHalCamCtrl->mPreviewMemory.camera_memory[frame->def.idx];//mPreviewHeap->mBuffers[frame->def.idx]; 615 } else { 616 data = NULL; 617 } 618 if(msgType) { 619 mStopCallbackLock.unlock(); 620 pcb(msgType, data, 0, metadata, mHalCamCtrl->mCallbackCookie); 621 } 622 ALOGD("end of cb"); 623 } 624 if(rcb != NULL) 625 { 626 if (mHalCamCtrl->mStoreMetaDataInFrame) 627 { 628 mStopCallbackLock.unlock(); 629 if(mHalCamCtrl->mStartRecording == true &&( mHalCamCtrl->mMsgEnabled & CAMERA_MSG_VIDEO_FRAME)) 630 rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME, 631 mHalCamCtrl->mRecordingMemory.metadata_memory[frame->def.idx], 632 0, mHalCamCtrl->mCallbackCookie); 633 } 634 else 635 { 636 if(mHalCamCtrl->mStartRecording == true &&( mHalCamCtrl->mMsgEnabled & CAMERA_MSG_VIDEO_FRAME)) 637 { 638 mStopCallbackLock.unlock(); 639 rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME, 640 mHalCamCtrl->mPreviewMemory.camera_memory[frame->def.idx], 641 0, mHalCamCtrl->mCallbackCookie); 642 } 643 } 644 } 645 646 /* Save the last displayed frame. We'll be using it to fill the gap between 647 when preview stops and postview start during snapshot.*/ 648 //mLastQueuedFrame = frame->def.frame; 649 /* 650 if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId, frame)) 651 { 652 ALOGE("BUF DONE FAILED"); 653 return BAD_VALUE; 654 } 655 */ 656 return NO_ERROR; 657 } 658 659 // --------------------------------------------------------------------------- 660 // QCameraStream_preview 661 // --------------------------------------------------------------------------- 662 663 QCameraStream_preview:: 664 QCameraStream_preview(int cameraId, camera_mode_t mode) 665 : QCameraStream(cameraId,mode), 666 mLastQueuedFrame(NULL), 667 mNumFDRcvd(0) 668 { 669 mHalCamCtrl = NULL; 670 ALOGE("%s: E", __func__); 671 ALOGE("%s: X", __func__); 672 } 673 // --------------------------------------------------------------------------- 674 // QCameraStream_preview 675 // --------------------------------------------------------------------------- 676 677 QCameraStream_preview::~QCameraStream_preview() { 678 ALOGV("%s: E", __func__); 679 if(mActive) { 680 stop(); 681 } 682 if(mInit) { 683 release(); 684 } 685 mInit = false; 686 mActive = false; 687 ALOGV("%s: X", __func__); 688 689 } 690 // --------------------------------------------------------------------------- 691 // QCameraStream_preview 692 // --------------------------------------------------------------------------- 693 694 status_t QCameraStream_preview::init() { 695 696 status_t ret = NO_ERROR; 697 ALOGV("%s: E", __func__); 698 699 ret = QCameraStream::initChannel (mCameraId, MM_CAMERA_CH_PREVIEW_MASK); 700 if (NO_ERROR!=ret) { 701 ALOGE("%s E: can't init native cammera preview ch\n",__func__); 702 return ret; 703 } 704 705 ALOGE("Debug : %s : initChannel",__func__); 706 /* register a notify into the mmmm_camera_t object*/ 707 (void) cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_PREVIEW, 708 preview_notify_cb, MM_CAMERA_REG_BUF_CB_INFINITE, 0, this); 709 ALOGE("Debug : %s : cam_evt_register_buf_notify",__func__); 710 buffer_handle_t *buffer_handle = NULL; 711 int tmp_stride = 0; 712 mInit = true; 713 return ret; 714 } 715 // --------------------------------------------------------------------------- 716 // QCameraStream_preview 717 // --------------------------------------------------------------------------- 718 719 status_t QCameraStream_preview::start() 720 { 721 ALOGV("%s: E", __func__); 722 status_t ret = NO_ERROR; 723 mm_camera_reg_buf_t *reg_buf=&mDisplayBuf; 724 725 Mutex::Autolock lock(mStopCallbackLock); 726 727 /* call start() in parent class to start the monitor thread*/ 728 //QCameraStream::start (); 729 setFormat(MM_CAMERA_CH_PREVIEW_MASK); 730 731 if(NO_ERROR!=initDisplayBuffers()){ 732 return BAD_VALUE; 733 } 734 ALOGE("Debug : %s : initDisplayBuffers",__func__); 735 ret = cam_config_prepare_buf(mCameraId, reg_buf); 736 ALOGE("Debug : %s : cam_config_prepare_buf",__func__); 737 if(ret != MM_CAMERA_OK) { 738 ALOGV("%s:reg preview buf err=%d\n", __func__, ret); 739 ret = BAD_VALUE; 740 }else 741 ret = NO_ERROR; 742 743 /* For preview, the OP_MODE we set is dependent upon whether we are 744 starting camera or camcorder. For snapshot, anyway we disable preview. 745 However, for ZSL we need to set OP_MODE to OP_MODE_ZSL and not 746 OP_MODE_VIDEO. We'll set that for now in CamCtrl. So in case of 747 ZSL we skip setting Mode here */ 748 749 if (!(myMode & CAMERA_ZSL_MODE)) { 750 ALOGE("Setting OP MODE to MM_CAMERA_OP_MODE_VIDEO"); 751 mm_camera_op_mode_type_t op_mode=MM_CAMERA_OP_MODE_VIDEO; 752 ret = cam_config_set_parm (mCameraId, MM_CAMERA_PARM_OP_MODE, 753 &op_mode); 754 ALOGE("OP Mode Set"); 755 756 if(MM_CAMERA_OK != ret) { 757 ALOGE("%s: X :set mode MM_CAMERA_OP_MODE_VIDEO err=%d\n", __func__, ret); 758 return BAD_VALUE; 759 } 760 }else { 761 ALOGE("Setting OP MODE to MM_CAMERA_OP_MODE_ZSL"); 762 mm_camera_op_mode_type_t op_mode=MM_CAMERA_OP_MODE_ZSL; 763 ret = cam_config_set_parm (mCameraId, MM_CAMERA_PARM_OP_MODE, 764 &op_mode); 765 if(MM_CAMERA_OK != ret) { 766 ALOGE("%s: X :set mode MM_CAMERA_OP_MODE_ZSL err=%d\n", __func__, ret); 767 return BAD_VALUE; 768 } 769 } 770 771 /* call mm_camera action start(...) */ 772 ALOGE("Starting Preview/Video Stream. "); 773 ret = cam_ops_action(mCameraId, TRUE, MM_CAMERA_OPS_PREVIEW, 0); 774 775 if (MM_CAMERA_OK != ret) { 776 ALOGE ("%s: preview streaming start err=%d\n", __func__, ret); 777 return BAD_VALUE; 778 } 779 780 ALOGE("Debug : %s : Preview streaming Started",__func__); 781 ret = NO_ERROR; 782 783 mActive = true; 784 ALOGE("%s: X", __func__); 785 return NO_ERROR; 786 } 787 788 789 // --------------------------------------------------------------------------- 790 // QCameraStream_preview 791 // --------------------------------------------------------------------------- 792 void QCameraStream_preview::stop() { 793 ALOGE("%s: E", __func__); 794 int ret=MM_CAMERA_OK; 795 796 if(!mActive) { 797 return; 798 } 799 mActive = false; 800 Mutex::Autolock lock(mStopCallbackLock); 801 /* unregister the notify fn from the mmmm_camera_t object*/ 802 803 /* call stop() in parent class to stop the monitor thread*/ 804 ret = cam_ops_action(mCameraId, FALSE, MM_CAMERA_OPS_PREVIEW, 0); 805 if(MM_CAMERA_OK != ret) { 806 ALOGE ("%s: camera preview stop err=%d\n", __func__, ret); 807 } 808 ALOGE("Debug : %s : Preview streaming Stopped",__func__); 809 ret = cam_config_unprepare_buf(mCameraId, MM_CAMERA_CH_PREVIEW); 810 if(ret != MM_CAMERA_OK) { 811 ALOGE("%s:Unreg preview buf err=%d\n", __func__, ret); 812 //ret = BAD_VALUE; 813 } 814 815 ALOGE("Debug : %s : Buffer Unprepared",__func__); 816 if (mDisplayBuf.preview.buf.mp != NULL) { 817 delete[] mDisplayBuf.preview.buf.mp; 818 } 819 /*free camera_memory handles and return buffer back to surface*/ 820 putBufferToSurface(); 821 822 ALOGE("%s: X", __func__); 823 824 } 825 // --------------------------------------------------------------------------- 826 // QCameraStream_preview 827 // --------------------------------------------------------------------------- 828 void QCameraStream_preview::release() { 829 830 ALOGE("%s : BEGIN",__func__); 831 int ret=MM_CAMERA_OK,i; 832 833 if(!mInit) 834 { 835 ALOGE("%s : Stream not Initalized",__func__); 836 return; 837 } 838 839 if(mActive) { 840 this->stop(); 841 } 842 843 ret= QCameraStream::deinitChannel(mCameraId, MM_CAMERA_CH_PREVIEW); 844 ALOGE("Debug : %s : De init Channel",__func__); 845 if(ret != MM_CAMERA_OK) { 846 ALOGE("%s:Deinit preview channel failed=%d\n", __func__, ret); 847 //ret = BAD_VALUE; 848 } 849 850 (void)cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_PREVIEW, 851 NULL, 852 (mm_camera_register_buf_cb_type_t)NULL, 853 NULL, 854 NULL); 855 mInit = false; 856 ALOGE("%s: END", __func__); 857 858 } 859 860 QCameraStream* 861 QCameraStream_preview::createInstance(int cameraId, 862 camera_mode_t mode) 863 { 864 QCameraStream* pme = new QCameraStream_preview(cameraId, mode); 865 return pme; 866 } 867 // --------------------------------------------------------------------------- 868 // QCameraStream_preview 869 // --------------------------------------------------------------------------- 870 871 void QCameraStream_preview::deleteInstance(QCameraStream *p) 872 { 873 if (p){ 874 ALOGV("%s: BEGIN", __func__); 875 p->release(); 876 delete p; 877 p = NULL; 878 ALOGV("%s: END", __func__); 879 } 880 } 881 882 883 /* Temp helper function */ 884 void *QCameraStream_preview::getLastQueuedFrame(void) 885 { 886 return mLastQueuedFrame; 887 } 888 889 status_t QCameraStream_preview::initPreviewOnlyBuffers() 890 { 891 /*1. for 7x27a, this shall not called; 892 2. this file shall be removed ASAP 893 so put a dummy function to just pass the compile*/ 894 return INVALID_OPERATION; 895 } 896 897 // --------------------------------------------------------------------------- 898 // No code beyone this line 899 // --------------------------------------------------------------------------- 900 }; // namespace android 901