1 /* 2 ** Copyright (c) 2012 The Linux Foundation. All rights reserved. 3 ** 4 ** Not a Contribution, Apache license notifications and license are retained 5 ** for attribution purposes only. 6 ** 7 ** Licensed under the Apache License, Version 2.0 (the "License"); 8 ** you may not use this file except in compliance with the License. 9 ** You may obtain a copy of the License at 10 ** 11 ** http://www.apache.org/licenses/LICENSE-2.0 12 ** 13 ** Unless required by applicable law or agreed to in writing, software 14 ** distributed under the License is distributed on an "AS IS" BASIS, 15 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 ** See the License for the specific language governing permissions and 17 ** limitations under the License. 18 */ 19 20 /*#error uncomment this for compiler test!*/ 21 22 #define LOG_TAG "QCameraHWI_Preview" 23 #include <utils/Log.h> 24 #include <utils/threads.h> 25 #include <fcntl.h> 26 #include <sys/mman.h> 27 #include "QCameraHAL.h" 28 #include "QCameraHWI.h" 29 #include <genlock.h> 30 #include <gralloc_priv.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 status_t QCameraStream_preview::getBufferFromSurface() { 40 int err = 0; 41 status_t ret = NO_ERROR; 42 int gralloc_usage; 43 struct ion_fd_data ion_info_fd; 44 preview_stream_ops_t *previewWindow = mHalCamCtrl->mPreviewWindow; 45 46 ALOGI(" %s : E ", __FUNCTION__); 47 48 if( previewWindow == NULL) { 49 ALOGE("%s: PreviewWindow = NULL", __func__); 50 return INVALID_OPERATION; 51 } 52 53 mHalCamCtrl->mPreviewMemoryLock.lock(); 54 mHalCamCtrl->mPreviewMemory.buffer_count = mNumBuffers; 55 err = previewWindow->set_buffer_count(previewWindow, mHalCamCtrl->mPreviewMemory.buffer_count ); 56 if (err != 0) { 57 ALOGE("set_buffer_count failed: %s (%d)", 58 strerror(-err), -err); 59 ret = UNKNOWN_ERROR; 60 goto end; 61 } 62 63 err = previewWindow->set_buffers_geometry(previewWindow, mWidth, mHeight, 64 mHalCamCtrl->getPreviewFormatInfo().Hal_format); 65 if (err != 0) { 66 ALOGE("set_buffers_geometry failed: %s (%d)", 67 strerror(-err), -err); 68 ret = UNKNOWN_ERROR; 69 goto end; 70 } 71 72 ret = p_mm_ops->ops->get_parm(mCameraHandle, MM_CAMERA_PARM_VFE_OUTPUT_ENABLE, &mVFEOutputs); 73 if(ret != MM_CAMERA_OK) { 74 ALOGE("get parm MM_CAMERA_PARM_VFE_OUTPUT_ENABLE failed"); 75 ret = BAD_VALUE; 76 goto end; 77 } 78 79 //as software encoder is used to encode 720p, to enhance the performance 80 //cashed pmem is used here 81 if(mVFEOutputs == 1) 82 gralloc_usage = CAMERA_GRALLOC_HEAP_ID | CAMERA_GRALLOC_FALLBACK_HEAP_ID; 83 else 84 gralloc_usage = CAMERA_GRALLOC_HEAP_ID | CAMERA_GRALLOC_FALLBACK_HEAP_ID | 85 CAMERA_GRALLOC_CACHING_ID; 86 err = previewWindow->set_usage(previewWindow, gralloc_usage); 87 if(err != 0) { 88 /* set_usage error out */ 89 ALOGE("%s: set_usage rc = %d", __func__, err); 90 ret = UNKNOWN_ERROR; 91 goto end; 92 } 93 ret = p_mm_ops->ops->get_parm(mCameraHandle, MM_CAMERA_PARM_HFR_FRAME_SKIP, &mHFRFrameSkip); 94 if(ret != MM_CAMERA_OK) { 95 ALOGE("get parm MM_CAMERA_PARM_HFR_FRAME_SKIP failed"); 96 ret = BAD_VALUE; 97 goto end; 98 } 99 for (int cnt = 0; cnt < mHalCamCtrl->mPreviewMemory.buffer_count; cnt++) { 100 int stride; 101 err = previewWindow->dequeue_buffer(previewWindow, 102 &mHalCamCtrl->mPreviewMemory.buffer_handle[cnt], 103 &mHalCamCtrl->mPreviewMemory.stride[cnt]); 104 if(!err) { 105 ALOGV("%s: dequeue buf hdl =%p", __func__, *mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]); 106 err = previewWindow->lock_buffer(previewWindow, 107 mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]); 108 // lock the buffer using genlock 109 ALOGV("%s: camera call genlock_lock, hdl=%p", 110 __FUNCTION__, (*mHalCamCtrl->mPreviewMemory.buffer_handle[cnt])); 111 if (GENLOCK_NO_ERROR != genlock_lock_buffer((native_handle_t *)(*mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]), 112 GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) { 113 ALOGE("%s: genlock_lock_buffer(WRITE) failed", __func__); 114 mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_UNLOCKED; 115 } else { 116 ALOGV("%s: genlock_lock_buffer hdl =%p", __func__, *mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]); 117 mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_LOCKED; 118 } 119 } else { 120 mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_NOT_OWNED; 121 ALOGE("%s: dequeue_buffer idx = %d err = %d", __func__, cnt, err); 122 } 123 124 ALOGV("%s: dequeue buf: %p\n", __func__, mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]); 125 126 if(err != 0) { 127 ALOGE("%s: dequeue_buffer failed: %s (%d)", __func__, 128 strerror(-err), -err); 129 ret = UNKNOWN_ERROR; 130 for(int i = 0; i < cnt; i++) { 131 if (BUFFER_LOCKED == mHalCamCtrl->mPreviewMemory.local_flag[i]) { 132 ALOGD("%s: camera call genlock_unlock", __func__); 133 if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t *) 134 (*(mHalCamCtrl->mPreviewMemory.buffer_handle[i])))) { 135 ALOGE("%s: genlock_unlock_buffer failed: hdl =%p", __func__, (*(mHalCamCtrl->mPreviewMemory.buffer_handle[i])) ); 136 } else { 137 mHalCamCtrl->mPreviewMemory.local_flag[i] = BUFFER_UNLOCKED; 138 } 139 } 140 if( mHalCamCtrl->mPreviewMemory.local_flag[i] != BUFFER_NOT_OWNED) { 141 err = previewWindow->cancel_buffer(previewWindow, 142 mHalCamCtrl->mPreviewMemory.buffer_handle[i]); 143 } 144 mHalCamCtrl->mPreviewMemory.local_flag[i] = BUFFER_NOT_OWNED; 145 ALOGD("%s: cancel_buffer: hdl =%p", __func__, (*mHalCamCtrl->mPreviewMemory.buffer_handle[i])); 146 mHalCamCtrl->mPreviewMemory.buffer_handle[i] = NULL; 147 } 148 memset(&mHalCamCtrl->mPreviewMemory, 0, sizeof(mHalCamCtrl->mPreviewMemory)); 149 goto end; 150 } 151 152 mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt] = 153 (struct private_handle_t *)(*mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]); 154 #ifdef USE_ION 155 mHalCamCtrl->mPreviewMemory.mem_info[cnt].main_ion_fd = open("/dev/ion", O_RDONLY); 156 if (mHalCamCtrl->mPreviewMemory.mem_info[cnt].main_ion_fd < 0) { 157 ALOGE("%s: failed: could not open ion device\n", __func__); 158 } else { 159 memset(&ion_info_fd, 0, sizeof(ion_info_fd)); 160 ion_info_fd.fd = mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->fd; 161 if (ioctl(mHalCamCtrl->mPreviewMemory.mem_info[cnt].main_ion_fd, 162 ION_IOC_IMPORT, &ion_info_fd) < 0) { 163 ALOGE("ION import failed\n"); 164 } 165 } 166 #endif 167 mHalCamCtrl->mPreviewMemory.camera_memory[cnt] = 168 mHalCamCtrl->mGetMemory(mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->fd, 169 mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->size, 170 1, 171 (void *)this); 172 ALOGD("%s: idx = %d, fd = %d, size = %d, offset = %d", __func__, 173 cnt, mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->fd, 174 mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->size, 175 mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->offset); 176 177 mHalCamCtrl->mPreviewMemory.mem_info[cnt].fd = 178 mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->fd; 179 mHalCamCtrl->mPreviewMemory.mem_info[cnt].size = 180 mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->size; 181 mHalCamCtrl->mPreviewMemory.mem_info[cnt].handle = ion_info_fd.handle; 182 } 183 184 memset(&mHalCamCtrl->mMetadata, 0, sizeof(mHalCamCtrl->mMetadata)); 185 memset(mHalCamCtrl->mFace, 0, sizeof(mHalCamCtrl->mFace)); 186 187 end: 188 mHalCamCtrl->mPreviewMemoryLock.unlock(); 189 190 ALOGI(" %s : X ",__func__); 191 return ret; 192 } 193 194 status_t QCameraStream_preview::putBufferToSurface() { 195 int err = 0; 196 status_t ret = NO_ERROR; 197 198 ALOGI(" %s : E ", __FUNCTION__); 199 200 mHalCamCtrl->mPreviewMemoryLock.lock(); 201 for (int cnt = 0; cnt < mHalCamCtrl->mPreviewMemory.buffer_count; cnt++) { 202 mHalCamCtrl->mPreviewMemory.camera_memory[cnt]->release(mHalCamCtrl->mPreviewMemory.camera_memory[cnt]); 203 #ifdef USE_ION 204 struct ion_handle_data ion_handle; 205 memset(&ion_handle, 0, sizeof(ion_handle)); 206 ion_handle.handle = mHalCamCtrl->mPreviewMemory.mem_info[cnt].handle; 207 if (ioctl(mHalCamCtrl->mPreviewMemory.mem_info[cnt].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) { 208 ALOGE("%s: ion free failed\n", __func__); 209 } 210 close(mHalCamCtrl->mPreviewMemory.mem_info[cnt].main_ion_fd); 211 #endif 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, handle =%p", __FUNCTION__, (*(mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]))); 217 continue; 218 } else { 219 220 ALOGD("%s: genlock_unlock_buffer, handle =%p", __FUNCTION__, (*(mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]))); 221 mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_UNLOCKED; 222 } 223 } 224 if( mHalCamCtrl->mPreviewMemory.local_flag[cnt] != BUFFER_NOT_OWNED) { 225 if (mHalCamCtrl->mPreviewWindow) { 226 err = mHalCamCtrl->mPreviewWindow->cancel_buffer(mHalCamCtrl->mPreviewWindow, 227 mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]); 228 ALOGD("%s: cancel_buffer: hdl =%p", __func__, (*mHalCamCtrl->mPreviewMemory.buffer_handle[cnt])); 229 } else { 230 ALOGE("%s: Preview window is NULL, cannot cancel_buffer: hdl =%p", 231 __func__, (*mHalCamCtrl->mPreviewMemory.buffer_handle[cnt])); 232 } 233 } 234 mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_NOT_OWNED; 235 ALOGD(" put buffer %d successfully", cnt); 236 } 237 mHalCamCtrl->mPreviewMemoryLock.unlock(); 238 memset(&mHalCamCtrl->mPreviewMemory, 0, sizeof(mHalCamCtrl->mPreviewMemory)); 239 ALOGI(" %s : X ",__FUNCTION__); 240 return NO_ERROR; 241 } 242 243 status_t QCameraStream_preview::initStream(uint8_t no_cb_needed, uint8_t stream_on) 244 { 245 int format = 0; 246 status_t ret = NO_ERROR; 247 int numMinUndequeuedBufs; 248 int err = 0; 249 250 ALOGI(" %s : E ", __FUNCTION__); 251 if (mHalCamCtrl->isNoDisplayMode()) { 252 mNumBuffers = PREVIEW_BUFFER_COUNT; 253 if(mHalCamCtrl->isZSLMode()) { 254 if(mNumBuffers < mHalCamCtrl->getZSLQueueDepth() + 3) { 255 mNumBuffers = mHalCamCtrl->getZSLQueueDepth() + 3; 256 } 257 } 258 } else { 259 if( mHalCamCtrl->mPreviewWindow == NULL) { 260 ALOGE("%s: PreviewWindow = NULL", __func__); 261 return INVALID_OPERATION; 262 } 263 numMinUndequeuedBufs = 0; 264 if(mHalCamCtrl->mPreviewWindow->get_min_undequeued_buffer_count) { 265 err = mHalCamCtrl->mPreviewWindow->get_min_undequeued_buffer_count( 266 mHalCamCtrl->mPreviewWindow, &numMinUndequeuedBufs); 267 if (err != 0) { 268 ALOGE("get_min_undequeued_buffer_count failed: %s (%d)", 269 strerror(-err), -err); 270 ret = UNKNOWN_ERROR; 271 goto end; 272 } 273 } 274 mNumBuffers = PREVIEW_BUFFER_COUNT + numMinUndequeuedBufs; 275 if(mHalCamCtrl->isZSLMode()) { 276 if(mHalCamCtrl->getZSLQueueDepth() > numMinUndequeuedBufs) 277 mNumBuffers += mHalCamCtrl->getZSLQueueDepth() - numMinUndequeuedBufs; 278 } 279 } 280 ret = QCameraStream::initStream(no_cb_needed, stream_on); 281 end: 282 ALOGI(" %s : X ", __FUNCTION__); 283 return ret; 284 } 285 286 287 status_t QCameraStream_preview::getBufferNoDisplay( ) 288 { 289 status_t ret = NO_ERROR; 290 uint32_t planes[VIDEO_MAX_PLANES]; 291 292 ALOGI("%s : E ", __FUNCTION__); 293 294 mHalCamCtrl->mPreviewMemoryLock.lock(); 295 memset(mDisplayBuf, 0, sizeof(mDisplayBuf)); 296 if (mHalCamCtrl->initHeapMem(&mHalCamCtrl->mNoDispPreviewMemory, 297 mNumBuffers, 298 mFrameOffsetInfo.frame_len, 299 MSM_PMEM_MAINIMG, 300 &mFrameOffsetInfo, 301 mDisplayBuf) < 0) { 302 ret = NO_MEMORY; 303 goto end; 304 } 305 306 memset(&mHalCamCtrl->mMetadata, 0, sizeof(mHalCamCtrl->mMetadata)); 307 memset(mHalCamCtrl->mFace, 0, sizeof(mHalCamCtrl->mFace)); 308 309 ALOGI(" %s : X ",__FUNCTION__); 310 end: 311 mHalCamCtrl->mPreviewMemoryLock.unlock(); 312 return ret; 313 } 314 315 status_t QCameraStream_preview::freeBufferNoDisplay() 316 { 317 ALOGI(" %s : E ", __FUNCTION__); 318 mHalCamCtrl->mPreviewMemoryLock.lock(); 319 mHalCamCtrl->releaseHeapMem(&mHalCamCtrl->mNoDispPreviewMemory); 320 memset(&mHalCamCtrl->mNoDispPreviewMemory, 0, sizeof(mHalCamCtrl->mNoDispPreviewMemory)); 321 mHalCamCtrl->mPreviewMemoryLock.unlock(); 322 ALOGI(" %s : X ",__FUNCTION__); 323 return NO_ERROR; 324 } 325 326 void QCameraStream_preview::notifyROIEvent(fd_roi_t roi) 327 { 328 switch (roi.type) { 329 case FD_ROI_TYPE_HEADER: 330 { 331 mDisplayLock.lock(); 332 mNumFDRcvd = 0; 333 memset(mHalCamCtrl->mFace, 0, sizeof(mHalCamCtrl->mFace)); 334 mHalCamCtrl->mMetadata.faces = mHalCamCtrl->mFace; 335 mHalCamCtrl->mMetadata.number_of_faces = roi.d.hdr.num_face_detected; 336 if(mHalCamCtrl->mMetadata.number_of_faces > MAX_ROI) 337 mHalCamCtrl->mMetadata.number_of_faces = MAX_ROI; 338 mDisplayLock.unlock(); 339 340 if (mHalCamCtrl->mMetadata.number_of_faces == 0) { 341 // Clear previous faces 342 if (mHalCamCtrl->mDataCb && (mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_METADATA)){ 343 ALOGE("%s: Face detection RIO callback", __func__); 344 mHalCamCtrl->mDataCb(CAMERA_MSG_PREVIEW_METADATA, NULL, 0, 345 &mHalCamCtrl->mMetadata, mHalCamCtrl->mCallbackCookie); 346 } 347 } 348 } 349 break; 350 case FD_ROI_TYPE_DATA: 351 { 352 mDisplayLock.lock(); 353 int idx = roi.d.data.idx; 354 if (idx >= mHalCamCtrl->mMetadata.number_of_faces) { 355 mDisplayLock.unlock(); 356 ALOGE("%s: idx %d out of boundary %d", 357 __func__, idx, mHalCamCtrl->mMetadata.number_of_faces); 358 break; 359 } 360 361 mHalCamCtrl->mFace[idx].id = roi.d.data.face.id; 362 mHalCamCtrl->mFace[idx].score = roi.d.data.face.score; 363 364 // top 365 mHalCamCtrl->mFace[idx].rect[0] = 366 roi.d.data.face.face_boundary.x*2000/mHalCamCtrl->mDimension.display_width - 1000; 367 //right 368 mHalCamCtrl->mFace[idx].rect[1] = 369 roi.d.data.face.face_boundary.y*2000/mHalCamCtrl->mDimension.display_height - 1000; 370 //bottom 371 mHalCamCtrl->mFace[idx].rect[2] = mHalCamCtrl->mFace[idx].rect[0] + 372 roi.d.data.face.face_boundary.dx*2000/mHalCamCtrl->mDimension.display_width; 373 //left 374 mHalCamCtrl->mFace[idx].rect[3] = mHalCamCtrl->mFace[idx].rect[1] + 375 roi.d.data.face.face_boundary.dy*2000/mHalCamCtrl->mDimension.display_height; 376 377 // Center of left eye 378 mHalCamCtrl->mFace[idx].left_eye[0] = 379 roi.d.data.face.left_eye_center[0]*2000/mHalCamCtrl->mDimension.display_width - 1000; 380 mHalCamCtrl->mFace[idx].left_eye[1] = 381 roi.d.data.face.left_eye_center[1]*2000/mHalCamCtrl->mDimension.display_height - 1000; 382 383 // Center of right eye 384 mHalCamCtrl->mFace[idx].right_eye[0] = 385 roi.d.data.face.right_eye_center[0]*2000/mHalCamCtrl->mDimension.display_width - 1000; 386 mHalCamCtrl->mFace[idx].right_eye[1] = 387 roi.d.data.face.right_eye_center[1]*2000/mHalCamCtrl->mDimension.display_height - 1000; 388 389 // Center of mouth 390 mHalCamCtrl->mFace[idx].mouth[0] = 391 roi.d.data.face.mouth_center[0]*2000/mHalCamCtrl->mDimension.display_width - 1000; 392 mHalCamCtrl->mFace[idx].mouth[1] = 393 roi.d.data.face.mouth_center[1]*2000/mHalCamCtrl->mDimension.display_height - 1000; 394 395 mHalCamCtrl->mFace[idx].smile_degree = roi.d.data.face.smile_degree; 396 mHalCamCtrl->mFace[idx].smile_score = roi.d.data.face.smile_confidence; 397 mHalCamCtrl->mFace[idx].blink_detected = roi.d.data.face.blink_detected; 398 mHalCamCtrl->mFace[idx].face_recognised = roi.d.data.face.is_face_recognised; 399 mHalCamCtrl->mFace[idx].gaze_angle = roi.d.data.face.gaze_angle; 400 401 /* newly added */ 402 // upscale by 2 to recover from demaen downscaling 403 mHalCamCtrl->mFace[idx].updown_dir = roi.d.data.face.updown_dir * 2; 404 mHalCamCtrl->mFace[idx].leftright_dir = roi.d.data.face.leftright_dir * 2; 405 mHalCamCtrl->mFace[idx].roll_dir = roi.d.data.face.roll_dir * 2; 406 407 mHalCamCtrl->mFace[idx].leye_blink = roi.d.data.face.left_blink; 408 mHalCamCtrl->mFace[idx].reye_blink = roi.d.data.face.right_blink; 409 mHalCamCtrl->mFace[idx].left_right_gaze = roi.d.data.face.left_right_gaze; 410 mHalCamCtrl->mFace[idx].top_bottom_gaze = roi.d.data.face.top_bottom_gaze; 411 ALOGE("%s: Face(%d, %d, %d, %d), leftEye(%d, %d), rightEye(%d, %d), mouth(%d, %d), smile(%d, %d), face_recg(%d)", __func__, 412 mHalCamCtrl->mFace[idx].rect[0], mHalCamCtrl->mFace[idx].rect[1], 413 mHalCamCtrl->mFace[idx].rect[2], mHalCamCtrl->mFace[idx].rect[3], 414 mHalCamCtrl->mFace[idx].left_eye[0], mHalCamCtrl->mFace[idx].left_eye[1], 415 mHalCamCtrl->mFace[idx].right_eye[0], mHalCamCtrl->mFace[idx].right_eye[1], 416 mHalCamCtrl->mFace[idx].mouth[0], mHalCamCtrl->mFace[idx].mouth[1], 417 mHalCamCtrl->mFace[idx].smile_degree, mHalCamCtrl->mFace[idx].smile_score, 418 mHalCamCtrl->mFace[idx].face_recognised); 419 ALOGE("%s: gaze(%d, %d, %d), updown(%d), leftright(%d), roll(%d), blink(%d, %d, %d)", __func__, 420 mHalCamCtrl->mFace[idx].gaze_angle, mHalCamCtrl->mFace[idx].left_right_gaze, 421 mHalCamCtrl->mFace[idx].top_bottom_gaze, mHalCamCtrl->mFace[idx].updown_dir, 422 mHalCamCtrl->mFace[idx].leftright_dir, mHalCamCtrl->mFace[idx].roll_dir, 423 mHalCamCtrl->mFace[idx].blink_detected, 424 mHalCamCtrl->mFace[idx].leye_blink, mHalCamCtrl->mFace[idx].reye_blink); 425 426 mNumFDRcvd++; 427 mDisplayLock.unlock(); 428 429 if (mNumFDRcvd == mHalCamCtrl->mMetadata.number_of_faces) { 430 if (mHalCamCtrl->mDataCb && (mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_METADATA)){ 431 ALOGE("%s: Face detection RIO callback with %d faces detected (score=%d)", __func__, mNumFDRcvd, mHalCamCtrl->mFace[idx].score); 432 mHalCamCtrl->mDataCb(CAMERA_MSG_PREVIEW_METADATA, NULL, 433 0, &mHalCamCtrl->mMetadata, mHalCamCtrl->mCallbackCookie); 434 } 435 } 436 } 437 break; 438 } 439 } 440 441 status_t QCameraStream_preview::initDisplayBuffers() 442 { 443 status_t ret = NO_ERROR; 444 uint8_t num_planes = mFrameOffsetInfo.num_planes; 445 uint32_t planes[VIDEO_MAX_PLANES]; 446 447 ALOGI("%s:BEGIN",__func__); 448 memset(&mHalCamCtrl->mMetadata, 0, sizeof(camera_frame_metadata_t)); 449 mHalCamCtrl->mPreviewMemoryLock.lock(); 450 memset(&mHalCamCtrl->mPreviewMemory, 0, sizeof(mHalCamCtrl->mPreviewMemory)); 451 mHalCamCtrl->mPreviewMemoryLock.unlock(); 452 memset(mNotifyBuffer, 0, sizeof(mNotifyBuffer)); 453 454 ret = getBufferFromSurface(); 455 if(ret != NO_ERROR) { 456 ALOGE("%s: cannot get memory from surface texture client, ret = %d", __func__, ret); 457 return ret; 458 } 459 460 /* set 4 buffers for display */ 461 mHalCamCtrl->mPreviewMemoryLock.lock(); 462 for(int i=0; i < num_planes; i++) 463 planes[i] = mFrameOffsetInfo.mp[i].len; 464 memset(mDisplayBuf, 0, sizeof(mm_camera_buf_def_t) * 2 * PREVIEW_BUFFER_COUNT); 465 /*allocate memory for the buffers*/ 466 for(int i = 0; i < mNumBuffers; i++){ 467 if (mHalCamCtrl->mPreviewMemory.private_buffer_handle[i] == NULL) 468 continue; 469 mHalCamCtrl->mPreviewMemory.addr_offset[i] = 470 mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->offset; 471 ALOGD("%s: idx = %d, fd = %d, size = %d, cbcr_offset = %d, y_offset = %d, " 472 "offset = %d, vaddr = 0x%lx", __func__, i, mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->fd, 473 mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->size, 474 planes[0], 0, 475 mHalCamCtrl->mPreviewMemory.addr_offset[i], 476 (long unsigned int)mHalCamCtrl->mPreviewMemory.camera_memory[i]->data); 477 mDisplayBuf[i].num_planes = num_planes; 478 479 /* Plane 0 needs to be set seperately. Set other planes 480 * in a loop. */ 481 mDisplayBuf[i].planes[0].length = planes[0]; 482 mDisplayBuf[i].planes[0].m.userptr = mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->fd; 483 mDisplayBuf[i].planes[0].data_offset = mFrameOffsetInfo.mp[0].offset; 484 mDisplayBuf[i].planes[0].reserved[0] =0;// mHalCamCtrl->mPreviewMemory.addr_offset[i]; // mDisplayBuf.preview.buf.mp[i].frame_offset; 485 for (int j = 1; j < num_planes; j++) { 486 mDisplayBuf[i].planes[j].length = planes[j]; 487 mDisplayBuf[i].planes[j].m.userptr = mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->fd; 488 mDisplayBuf[i].planes[j].data_offset = mFrameOffsetInfo.mp[j].offset; 489 mDisplayBuf[i].planes[j].reserved[0] = 490 mDisplayBuf[i].planes[j-1].reserved[0] + 491 mDisplayBuf[i].planes[j-1].length; 492 } 493 494 for (int j = 0; j < num_planes; j++) 495 ALOGD("Planes: %d length: %d userptr: %lu offset: %d\n", j, 496 mDisplayBuf[i].planes[j].length, 497 mDisplayBuf[i].planes[j].m.userptr, 498 mDisplayBuf[i].planes[j].reserved[0]); 499 500 mDisplayBuf[i].fd = mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->fd; 501 ALOGD("DEBUG2:Display buf[%d] fd:%d",i,mDisplayBuf[i].fd); 502 mDisplayBuf[i].frame_len = mFrameOffsetInfo.frame_len; 503 mDisplayBuf[i].buffer = (void *)mHalCamCtrl->mPreviewMemory.camera_memory[i]->data; 504 mDisplayBuf[i].mem_info = (void *)&mHalCamCtrl->mPreviewMemory.mem_info[i]; 505 }/*end of for loop*/ 506 507 /* register the streaming buffers for the channel*/ 508 mHalCamCtrl->mPreviewMemoryLock.unlock(); 509 ALOGI("%s:END",__func__); 510 return NO_ERROR; 511 512 error: 513 mHalCamCtrl->mPreviewMemoryLock.unlock(); 514 putBufferToSurface(); 515 516 ALOGV("%s: X", __func__); 517 return ret; 518 } 519 520 status_t QCameraStream_preview::initPreviewOnlyBuffers() 521 { 522 status_t ret = NO_ERROR; 523 uint8_t num_planes = mFrameOffsetInfo.num_planes; 524 uint32_t planes[VIDEO_MAX_PLANES]; 525 526 ALOGI("%s:BEGIN",__func__); 527 memset(&mHalCamCtrl->mMetadata, 0, sizeof(camera_frame_metadata_t)); 528 mHalCamCtrl->mPreviewMemoryLock.lock(); 529 memset(&mHalCamCtrl->mNoDispPreviewMemory, 0, sizeof(mHalCamCtrl->mNoDispPreviewMemory)); 530 mHalCamCtrl->mPreviewMemoryLock.unlock(); 531 532 memset(mNotifyBuffer, 0, sizeof(mNotifyBuffer)); 533 memset(mDisplayBuf, 0, sizeof(mDisplayBuf)); 534 535 ret = getBufferNoDisplay( ); 536 if(ret != NO_ERROR) { 537 ALOGE("%s: cannot get memory from surface texture client, ret = %d", __func__, ret); 538 return ret; 539 } 540 541 ALOGI("%s:END",__func__); 542 return NO_ERROR; 543 } 544 545 546 void QCameraStream_preview::dumpFrameToFile(mm_camera_buf_def_t *newFrame) 547 { 548 int32_t enabled = 0; 549 int frm_num; 550 uint32_t skip_mode; 551 char value[PROPERTY_VALUE_MAX]; 552 char buf[32]; 553 int w, h; 554 static int count = 0; 555 cam_ctrl_dimension_t dim; 556 int file_fd; 557 int rc = 0; 558 int len; 559 unsigned long addr; 560 unsigned long * tmp = (unsigned long *)newFrame->buffer; 561 addr = *tmp; 562 status_t ret = p_mm_ops->ops->get_parm(mCameraHandle, 563 MM_CAMERA_PARM_DIMENSION, &dim); 564 565 w = dim.display_width; 566 h = dim.display_height; 567 len = (w * h)*3/2; 568 count++; 569 if(count < 100) { 570 snprintf(buf, sizeof(buf), "/data/mzhu%d.yuv", count); 571 file_fd = open(buf, O_RDWR | O_CREAT, 0777); 572 573 rc = write(file_fd, (const void *)addr, len); 574 ALOGE("%s: file='%s', vaddr_old=0x%x, addr_map = 0x%p, len = %d, rc = %d", 575 __func__, buf, (uint32_t)newFrame->buffer, (void *)addr, len, rc); 576 close(file_fd); 577 ALOGE("%s: dump %s, rc = %d, len = %d", __func__, buf, rc, len); 578 } 579 } 580 581 status_t QCameraStream_preview::processPreviewFrameWithDisplay(mm_camera_super_buf_t *frame) 582 { 583 ALOGV("%s",__func__); 584 int err = 0; 585 int msgType = 0; 586 int i; 587 camera_memory_t *data = NULL; 588 camera_frame_metadata_t *metadata = NULL; 589 int preview_buf_idx = frame->bufs[0]->buf_idx; 590 591 if(!mActive) { 592 ALOGE("Preview Stopped. Returning callback"); 593 return NO_ERROR; 594 } 595 596 if(mHalCamCtrl==NULL) { 597 ALOGE("%s: X: HAL control object not set",__func__); 598 /*Call buf done*/ 599 return BAD_VALUE; 600 } 601 602 if(mFirstFrameRcvd == false) { 603 mFirstFrameRcvd = true; 604 } 605 606 if (UNLIKELY(mHalCamCtrl->mDebugFps)) { 607 mHalCamCtrl->debugShowPreviewFPS(); 608 } 609 mHalCamCtrl->dumpFrameToFile(frame->bufs[0], HAL_DUMP_FRM_PREVIEW); 610 611 mHalCamCtrl->mPreviewMemoryLock.lock(); 612 mNotifyBuffer[preview_buf_idx] = *frame; 613 614 ALOGD("<DEBUG2>: Received Frame fd:%d placed in index:%d db[index].fd:%d", 615 frame->bufs[0]->fd, preview_buf_idx, 616 mHalCamCtrl->mPreviewMemory.private_buffer_handle[preview_buf_idx]->fd); 617 618 ALOGI("Enqueue buf handle %p\n", 619 mHalCamCtrl->mPreviewMemory.buffer_handle[preview_buf_idx]); 620 ALOGD("%s: camera call genlock_unlock", __FUNCTION__); 621 if (BUFFER_LOCKED == mHalCamCtrl->mPreviewMemory.local_flag[preview_buf_idx]) { 622 ALOGD("%s: genlock_unlock_buffer hdl =%p", __FUNCTION__, (*mHalCamCtrl->mPreviewMemory.buffer_handle[preview_buf_idx])); 623 if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t*) 624 (*mHalCamCtrl->mPreviewMemory.buffer_handle[preview_buf_idx]))) { 625 ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__); 626 } else { 627 mHalCamCtrl->mPreviewMemory.local_flag[preview_buf_idx] = BUFFER_UNLOCKED; 628 } 629 } else { 630 ALOGE("%s: buffer to be enqueued is not locked", __FUNCTION__); 631 } 632 633 mHalCamCtrl->cache_ops(&mHalCamCtrl->mPreviewMemory.mem_info[preview_buf_idx], 634 (void *)mHalCamCtrl->mPreviewMemory.camera_memory[preview_buf_idx]->data, 635 ION_IOC_CLEAN_CACHES); 636 mHalCamCtrl->cache_ops(&mHalCamCtrl->mPreviewMemory.mem_info[preview_buf_idx], 637 (void *)mHalCamCtrl->mPreviewMemory.camera_memory[preview_buf_idx]->data, 638 ION_IOC_CLEAN_INV_CACHES); 639 640 if(mHFRFrameSkip == 1) 641 { 642 ALOGE("In HFR Frame skip"); 643 const char *str = mHalCamCtrl->mParameters.get( 644 QCameraParameters::KEY_QC_VIDEO_HIGH_FRAME_RATE); 645 if(str != NULL){ 646 int is_hfr_off = 0; 647 mHFRFrameCnt++; 648 if(!strcmp(str, QCameraParameters::VIDEO_HFR_OFF)) { 649 is_hfr_off = 1; 650 err = mHalCamCtrl->mPreviewWindow->enqueue_buffer(mHalCamCtrl->mPreviewWindow, 651 (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[preview_buf_idx]); 652 } else if (!strcmp(str, QCameraParameters::VIDEO_HFR_2X)) { 653 mHFRFrameCnt %= 2; 654 } else if (!strcmp(str, QCameraParameters::VIDEO_HFR_3X)) { 655 mHFRFrameCnt %= 3; 656 } else if (!strcmp(str, QCameraParameters::VIDEO_HFR_4X)) { 657 mHFRFrameCnt %= 4; 658 } 659 if(mHFRFrameCnt == 0) 660 err = mHalCamCtrl->mPreviewWindow->enqueue_buffer(mHalCamCtrl->mPreviewWindow, 661 (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[preview_buf_idx]); 662 else if(!is_hfr_off) 663 err = mHalCamCtrl->mPreviewWindow->cancel_buffer(mHalCamCtrl->mPreviewWindow, 664 (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[preview_buf_idx]); 665 } else 666 err = mHalCamCtrl->mPreviewWindow->enqueue_buffer(mHalCamCtrl->mPreviewWindow, 667 (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[preview_buf_idx]); 668 } else { 669 err = mHalCamCtrl->mPreviewWindow->enqueue_buffer(mHalCamCtrl->mPreviewWindow, 670 (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[preview_buf_idx]); 671 } 672 if(err != 0) { 673 ALOGE("%s: enqueue_buffer failed, err = %d", __func__, err); 674 } else { 675 ALOGD("%s: enqueue_buffer hdl=%p", __func__, *mHalCamCtrl->mPreviewMemory.buffer_handle[preview_buf_idx]); 676 mHalCamCtrl->mPreviewMemory.local_flag[preview_buf_idx] = BUFFER_NOT_OWNED; 677 } 678 buffer_handle_t *buffer_handle = NULL; 679 int tmp_stride = 0; 680 err = mHalCamCtrl->mPreviewWindow->dequeue_buffer(mHalCamCtrl->mPreviewWindow, 681 &buffer_handle, &tmp_stride); 682 if (err == NO_ERROR && buffer_handle != NULL) { 683 684 ALOGD("%s: dequed buf hdl =%p", __func__, *buffer_handle); 685 for(i = 0; i < mHalCamCtrl->mPreviewMemory.buffer_count; i++) { 686 if(mHalCamCtrl->mPreviewMemory.buffer_handle[i] == buffer_handle) { 687 ALOGE("<DEBUG2>:Found buffer in idx:%d",i); 688 mHalCamCtrl->mPreviewMemory.local_flag[i] = BUFFER_UNLOCKED; 689 break; 690 } 691 } 692 if (i < mHalCamCtrl->mPreviewMemory.buffer_count ) { 693 err = mHalCamCtrl->mPreviewWindow->lock_buffer(mHalCamCtrl->mPreviewWindow, buffer_handle); 694 ALOGD("%s: camera call genlock_lock: hdl =%p", __func__, *buffer_handle); 695 if (GENLOCK_FAILURE == genlock_lock_buffer((native_handle_t*)(*buffer_handle), GENLOCK_WRITE_LOCK, 696 GENLOCK_MAX_TIMEOUT)) { 697 ALOGE("%s: genlock_lock_buffer(WRITE) failed", __func__); 698 } else { 699 mHalCamCtrl->mPreviewMemory.local_flag[i] = BUFFER_LOCKED; 700 701 if(MM_CAMERA_OK != p_mm_ops->ops->qbuf(mCameraHandle, mChannelId, mNotifyBuffer[i].bufs[0])) { 702 703 ALOGE("BUF DONE FAILED"); 704 } 705 mHalCamCtrl->cache_ops((QCameraHalMemInfo_t *)(mNotifyBuffer[i].bufs[0]->mem_info), 706 mNotifyBuffer[i].bufs[0]->buffer, 707 ION_IOC_INV_CACHES); 708 } 709 } 710 } else 711 ALOGE("%s: enqueue_buffer idx = %d, no free buffer from display now", __func__, frame->bufs[0]->buf_idx); 712 /* Save the last displayed frame. We'll be using it to fill the gap between 713 when preview stops and postview start during snapshot.*/ 714 mLastQueuedFrame = &(mDisplayBuf[preview_buf_idx]); 715 mHalCamCtrl->mPreviewMemoryLock.unlock(); 716 717 nsecs_t timeStamp = seconds_to_nanoseconds(frame->bufs[0]->ts.tv_sec) ; 718 timeStamp += frame->bufs[0]->ts.tv_nsec; 719 ALOGD("Message enabled = 0x%x", mHalCamCtrl->mMsgEnabled); 720 721 camera_memory_t *previewMem = NULL; 722 723 if (mHalCamCtrl->mDataCb != NULL) { 724 ALOGD("%s: mMsgEnabled =0x%x, preview format =%d", __func__, 725 mHalCamCtrl->mMsgEnabled, mHalCamCtrl->mPreviewFormat); 726 //Sending preview callback if corresponding Msgs are enabled 727 if(mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) { 728 ALOGE("Q%s: PCB callback enabled", __func__); 729 msgType |= CAMERA_MSG_PREVIEW_FRAME; 730 int previewBufSize; 731 /* The preview buffer size sent back in the callback should be (width*height*bytes_per_pixel) 732 * As all preview formats we support, use 12 bits per pixel, buffer size = previewWidth * previewHeight * 3/2. 733 * We need to put a check if some other formats are supported in future. (punits) */ 734 if ((mHalCamCtrl->mPreviewFormat == CAMERA_YUV_420_NV21) || 735 (mHalCamCtrl->mPreviewFormat == CAMERA_YUV_420_NV12) || 736 (mHalCamCtrl->mPreviewFormat == CAMERA_YUV_420_YV12)) 737 { 738 if(mHalCamCtrl->mPreviewFormat == CAMERA_YUV_420_YV12) { 739 previewBufSize = ((mHalCamCtrl->mPreviewWidth+15)/16) * 16 * mHalCamCtrl->mPreviewHeight + 740 ((mHalCamCtrl->mPreviewWidth/2+15)/16) * 16* mHalCamCtrl->mPreviewHeight; 741 } else { 742 previewBufSize = mHalCamCtrl->mPreviewWidth * mHalCamCtrl->mPreviewHeight * 3/2; 743 } 744 if(previewBufSize != mHalCamCtrl->mPreviewMemory.private_buffer_handle[preview_buf_idx]->size) { 745 previewMem = mHalCamCtrl->mGetMemory(mHalCamCtrl->mPreviewMemory.private_buffer_handle[preview_buf_idx]->fd, 746 previewBufSize, 1, mHalCamCtrl->mCallbackCookie); 747 if (!previewMem || !previewMem->data) { 748 ALOGE("%s: mGetMemory failed.\n", __func__); 749 } else { 750 data = previewMem; 751 } 752 } else 753 data = mHalCamCtrl->mPreviewMemory.camera_memory[preview_buf_idx]; 754 } else { 755 data = mHalCamCtrl->mPreviewMemory.camera_memory[preview_buf_idx]; 756 ALOGE("Invalid preview format, buffer size in preview callback may be wrong."); 757 } 758 } else { 759 data = NULL; 760 } 761 if(msgType && mActive) { 762 mHalCamCtrl->mDataCb(msgType, data, 0, metadata, mHalCamCtrl->mCallbackCookie); 763 } 764 if (previewMem) { 765 previewMem->release(previewMem); 766 } 767 ALOGD("end of cb"); 768 } else { 769 ALOGD("%s PCB is not enabled", __func__); 770 } 771 if(mHalCamCtrl->mDataCbTimestamp != NULL && mVFEOutputs == 1) 772 { 773 int flagwait = 1; 774 if(mHalCamCtrl->mStartRecording == true && 775 ( mHalCamCtrl->mMsgEnabled & CAMERA_MSG_VIDEO_FRAME)) 776 { 777 if (mHalCamCtrl->mStoreMetaDataInFrame) 778 { 779 if(mHalCamCtrl->mRecordingMemory.metadata_memory[preview_buf_idx]) 780 { 781 flagwait = 1; 782 mHalCamCtrl->mDataCbTimestamp(timeStamp, CAMERA_MSG_VIDEO_FRAME, 783 mHalCamCtrl->mRecordingMemory.metadata_memory[preview_buf_idx], 784 0, mHalCamCtrl->mCallbackCookie); 785 }else 786 flagwait = 0; 787 } 788 else 789 { 790 mHalCamCtrl->mDataCbTimestamp(timeStamp, CAMERA_MSG_VIDEO_FRAME, 791 mHalCamCtrl->mPreviewMemory.camera_memory[preview_buf_idx], 792 0, mHalCamCtrl->mCallbackCookie); 793 } 794 795 if(flagwait){ 796 Mutex::Autolock rLock(&mHalCamCtrl->mRecordFrameLock); 797 if (mHalCamCtrl->mReleasedRecordingFrame != true) { 798 mHalCamCtrl->mRecordWait.wait(mHalCamCtrl->mRecordFrameLock); 799 } 800 mHalCamCtrl->mReleasedRecordingFrame = false; 801 } 802 } 803 } 804 return NO_ERROR; 805 } 806 807 808 status_t QCameraStream_preview::processPreviewFrameWithOutDisplay( 809 mm_camera_super_buf_t *frame) 810 { 811 ALOGV("%s",__func__); 812 int err = 0; 813 int msgType = 0; 814 int i; 815 camera_memory_t *data = NULL; 816 camera_frame_metadata_t *metadata = NULL; 817 int preview_buf_idx = frame->bufs[0]->buf_idx; 818 819 if(mHalCamCtrl==NULL) { 820 ALOGE("%s: X: HAL control object not set",__func__); 821 /*Call buf done*/ 822 return BAD_VALUE; 823 } 824 825 if (UNLIKELY(mHalCamCtrl->mDebugFps)) { 826 mHalCamCtrl->debugShowPreviewFPS(); 827 } 828 mHalCamCtrl->dumpFrameToFile(frame->bufs[0], HAL_DUMP_FRM_PREVIEW); 829 830 mHalCamCtrl->mPreviewMemoryLock.lock(); 831 mNotifyBuffer[preview_buf_idx] = *frame; 832 833 /* Save the last displayed frame. We'll be using it to fill the gap between 834 when preview stops and postview start during snapshot.*/ 835 mLastQueuedFrame = &(mDisplayBuf[frame->bufs[0]->buf_idx]); 836 mHalCamCtrl->mPreviewMemoryLock.unlock(); 837 838 ALOGD("Message enabled = 0x%x", mHalCamCtrl->mMsgEnabled); 839 840 mHalCamCtrl->cache_ops(&mHalCamCtrl->mNoDispPreviewMemory.mem_info[preview_buf_idx], 841 (void *)mHalCamCtrl->mNoDispPreviewMemory.camera_memory[preview_buf_idx]->data, 842 ION_IOC_CLEAN_CACHES); 843 844 if (mHalCamCtrl->mDataCb != NULL) { 845 //Sending preview callback if corresponding Msgs are enabled 846 if(mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) { 847 msgType |= CAMERA_MSG_PREVIEW_FRAME; 848 int previewBufSize; 849 /* For CTS : Forcing preview memory buffer lenth to be 850 'previewWidth * previewHeight * 3/2'. 851 Needed when gralloc allocated extra memory.*/ 852 //Can add this check for other formats as well. 853 data = mHalCamCtrl->mNoDispPreviewMemory.camera_memory[preview_buf_idx];//mPreviewHeap->mBuffers[frame->bufs[0]->buf_idx]; 854 } else { 855 data = NULL; 856 } 857 858 if(mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_METADATA){ 859 msgType |= CAMERA_MSG_PREVIEW_METADATA; 860 metadata = &mHalCamCtrl->mMetadata; 861 } else { 862 metadata = NULL; 863 } 864 if(mActive && msgType) { 865 mHalCamCtrl->mDataCb(msgType, data, 0, metadata, mHalCamCtrl->mCallbackCookie); 866 } 867 868 if(MM_CAMERA_OK !=p_mm_ops->ops->qbuf(mCameraHandle, mChannelId, mNotifyBuffer[preview_buf_idx].bufs[0])) { 869 ALOGE("BUF DONE FAILED"); 870 } 871 mHalCamCtrl->cache_ops((QCameraHalMemInfo_t *)(mNotifyBuffer[preview_buf_idx].bufs[0]->mem_info), 872 mNotifyBuffer[preview_buf_idx].bufs[0]->buffer, 873 ION_IOC_INV_CACHES); 874 ALOGD("end of cb"); 875 } 876 877 return NO_ERROR; 878 } 879 880 status_t QCameraStream_preview::processPreviewFrame ( 881 mm_camera_super_buf_t *frame) 882 { 883 if (mHalCamCtrl->isNoDisplayMode()) { 884 return processPreviewFrameWithOutDisplay(frame); 885 } else { 886 return processPreviewFrameWithDisplay(frame); 887 } 888 } 889 890 // --------------------------------------------------------------------------- 891 // QCameraStream_preview 892 // --------------------------------------------------------------------------- 893 894 QCameraStream_preview::QCameraStream_preview(uint32_t CameraHandle, 895 uint32_t ChannelId, 896 uint32_t Width, 897 uint32_t Height, 898 uint32_t Format, 899 uint8_t NumBuffers, 900 mm_camera_vtbl_t *mm_ops, 901 mm_camera_img_mode imgmode, 902 camera_mode_t mode, 903 QCameraHardwareInterface* camCtrl) 904 :QCameraStream(CameraHandle, 905 ChannelId, 906 Width, 907 Height, 908 Format, 909 NumBuffers, 910 mm_ops, 911 imgmode, 912 mode, 913 camCtrl), 914 mLastQueuedFrame(NULL), 915 mNumFDRcvd(0) 916 { 917 } 918 // --------------------------------------------------------------------------- 919 // QCameraStream_preview 920 // --------------------------------------------------------------------------- 921 922 QCameraStream_preview::~QCameraStream_preview() { 923 ALOGV("%s: E", __func__); 924 release(); 925 ALOGV("%s: X", __func__); 926 927 } 928 929 // --------------------------------------------------------------------------- 930 // QCameraStream_preview 931 // --------------------------------------------------------------------------- 932 void QCameraStream_preview::release() { 933 streamOff(0); 934 deinitStream(); 935 } 936 937 void *QCameraStream_preview::getLastQueuedFrame(void) 938 { 939 return mLastQueuedFrame; 940 } 941 942 int32_t QCameraStream_preview::setCrop() 943 { 944 int32_t rc = QCameraStream::setCrop(); 945 if (0 == rc) { 946 if (!mHalCamCtrl->mSmoothZoomRunning && mHalCamCtrl->mPreviewWindow) { 947 rc = mHalCamCtrl->mPreviewWindow->set_crop( 948 mHalCamCtrl->mPreviewWindow, 949 mCrop.offset_x, 950 mCrop.offset_y, 951 mCrop.offset_x + mCrop.width, 952 mCrop.offset_y + mCrop.height); 953 } 954 } 955 return rc; 956 } 957 958 int QCameraStream_preview::getBuf(mm_camera_frame_len_offset *frame_offset_info, 959 uint8_t num_bufs, 960 uint8_t *initial_reg_flag, 961 mm_camera_buf_def_t *bufs) 962 { 963 int ret = 0; 964 ALOGE("%s:BEGIN",__func__); 965 966 if (num_bufs > mNumBuffers) { 967 mNumBuffers = num_bufs; 968 } 969 if ((mNumBuffers == 0) || (mNumBuffers > MM_CAMERA_MAX_NUM_FRAMES)) { 970 ALOGE("%s: Invalid number of buffers (=%d) requested!", 971 __func__, mNumBuffers); 972 return BAD_VALUE; 973 } 974 975 memcpy(&mFrameOffsetInfo, frame_offset_info, sizeof(mFrameOffsetInfo)); 976 if (mHalCamCtrl->isNoDisplayMode()) { 977 ret = initPreviewOnlyBuffers(); 978 } else { 979 ret = initDisplayBuffers(); 980 } 981 ALOGD("Debug : %s : initDisplayBuffers",__func__); 982 for(int i = 0; i < num_bufs; i++) { 983 bufs[i] = mDisplayBuf[i]; 984 initial_reg_flag[i] = true; 985 } 986 987 ALOGV("%s: X - ret = %d ", __func__, ret); 988 return ret; 989 } 990 991 int QCameraStream_preview::putBuf(uint8_t num_bufs, mm_camera_buf_def_t *bufs) 992 { 993 int ret = 0; 994 ALOGE(" %s : E ", __func__); 995 if (mHalCamCtrl->isNoDisplayMode()) { 996 ret = freeBufferNoDisplay(); 997 } else { 998 ret = putBufferToSurface(); 999 } 1000 ALOGI(" %s : X ",__func__); 1001 return ret; 1002 } 1003 1004 // --------------------------------------------------------------------------- 1005 // No code beyone this line 1006 // --------------------------------------------------------------------------- 1007 }; // namespace android 1008