1 /* Copyright (c) 2012-2014, The Linux Foundataion. All rights reserved. 2 * 3 * Redistribution and use in source and binary forms, with or without 4 * modification, are permitted provided that the following conditions are 5 * met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above 9 * copyright notice, this list of conditions and the following 10 * disclaimer in the documentation and/or other materials provided 11 * with the distribution. 12 * * Neither the name of The Linux Foundation nor the names of its 13 * contributors may be used to endorse or promote products derived 14 * from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 */ 29 30 #define LOG_TAG "QCamera2HWI" 31 32 #include <time.h> 33 #include <fcntl.h> 34 #include <utils/Errors.h> 35 #include <utils/Timers.h> 36 #include "QCamera2HWI.h" 37 38 namespace qcamera { 39 40 /*=========================================================================== 41 * FUNCTION : zsl_channel_cb 42 * 43 * DESCRIPTION: helper function to handle ZSL superbuf callback directly from 44 * mm-camera-interface 45 * 46 * PARAMETERS : 47 * @recvd_frame : received super buffer 48 * @userdata : user data ptr 49 * 50 * RETURN : None 51 * 52 * NOTE : recvd_frame will be released after this call by caller, so if 53 * async operation needed for recvd_frame, it's our responsibility 54 * to save a copy for this variable to be used later. 55 *==========================================================================*/ 56 void QCamera2HardwareInterface::zsl_channel_cb(mm_camera_super_buf_t *recvd_frame, 57 void *userdata) 58 { 59 CDBG_HIGH("[KPI Perf] %s: E",__func__); 60 char value[PROPERTY_VALUE_MAX]; 61 bool dump_raw = false; 62 bool dump_yuv = false; 63 bool log_matching = false; 64 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 65 if (pme == NULL || 66 pme->mCameraHandle == NULL || 67 pme->mCameraHandle->camera_handle != recvd_frame->camera_handle){ 68 ALOGE("%s: camera obj not valid", __func__); 69 return; 70 } 71 72 QCameraChannel *pChannel = pme->m_channels[QCAMERA_CH_TYPE_ZSL]; 73 if (pChannel == NULL || 74 pChannel->getMyHandle() != recvd_frame->ch_id) { 75 ALOGE("%s: ZSL channel doesn't exist, return here", __func__); 76 return; 77 } 78 79 if(pme->mParameters.isSceneSelectionEnabled() && 80 !pme->m_stateMachine.isCaptureRunning()) { 81 pme->selectScene(pChannel, recvd_frame); 82 pChannel->bufDone(recvd_frame); 83 return; 84 } 85 86 CDBG_HIGH("%s: [ZSL Retro] Frame CB Unlock : %d, is AEC Locked: %d", 87 __func__, recvd_frame->bUnlockAEC, pme->m_bLedAfAecLock); 88 if(recvd_frame->bUnlockAEC && pme->m_bLedAfAecLock) { 89 ALOGI("%s : [ZSL Retro] LED assisted AF Release AEC Lock\n", __func__); 90 pme->mParameters.setAecLock("false"); 91 pme->mParameters.commitParameters(); 92 pme->m_bLedAfAecLock = FALSE ; 93 } 94 95 // Check if retro-active frames are completed and camera is 96 // ready to go ahead with LED estimation for regular frames 97 if (recvd_frame->bReadyForPrepareSnapshot) { 98 // Send an event 99 CDBG_HIGH("%s: [ZSL Retro] Ready for Prepare Snapshot, signal ", __func__); 100 qcamera_sm_internal_evt_payload_t *payload = 101 (qcamera_sm_internal_evt_payload_t *)malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 102 if (NULL != payload) { 103 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 104 payload->evt_type = QCAMERA_INTERNAL_EVT_READY_FOR_SNAPSHOT; 105 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 106 if (rc != NO_ERROR) { 107 ALOGE("%s: processEvt Ready for Snaphot failed", __func__); 108 free(payload); 109 payload = NULL; 110 } 111 } else { 112 ALOGE("%s: No memory for prepare signal event detect" 113 " qcamera_sm_internal_evt_payload_t", __func__); 114 } 115 } 116 117 // save a copy for the superbuf 118 mm_camera_super_buf_t* frame = 119 (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t)); 120 if (frame == NULL) { 121 ALOGE("%s: Error allocating memory to save received_frame structure.", __func__); 122 pChannel->bufDone(recvd_frame); 123 return; 124 } 125 *frame = *recvd_frame; 126 127 if (recvd_frame->num_bufs > 0) { 128 ALOGI("[KPI Perf] %s: superbuf frame_idx %d", __func__, 129 recvd_frame->bufs[0]->frame_idx); 130 } 131 132 // DUMP RAW if available 133 property_get("persist.camera.zsl_raw", value, "0"); 134 dump_raw = atoi(value) > 0 ? true : false; 135 if ( dump_raw ) { 136 for ( int i= 0 ; i < recvd_frame->num_bufs ; i++ ) { 137 if ( recvd_frame->bufs[i]->stream_type == CAM_STREAM_TYPE_RAW ) { 138 mm_camera_buf_def_t * raw_frame = recvd_frame->bufs[i]; 139 QCameraStream *pStream = pChannel->getStreamByHandle(raw_frame->stream_id); 140 if ( NULL != pStream ) { 141 pme->dumpFrameToFile(pStream, raw_frame, QCAMERA_DUMP_FRM_RAW); 142 } 143 break; 144 } 145 } 146 } 147 148 // DUMP YUV before reprocess if needed 149 property_get("persist.camera.zsl_yuv", value, "0"); 150 dump_yuv = atoi(value) > 0 ? true : false; 151 if ( dump_yuv ) { 152 for ( int i= 0 ; i < recvd_frame->num_bufs ; i++ ) { 153 if ( recvd_frame->bufs[i]->stream_type == CAM_STREAM_TYPE_SNAPSHOT ) { 154 mm_camera_buf_def_t * yuv_frame = recvd_frame->bufs[i]; 155 QCameraStream *pStream = pChannel->getStreamByHandle(yuv_frame->stream_id); 156 if ( NULL != pStream ) { 157 pme->dumpFrameToFile(pStream, yuv_frame, QCAMERA_DUMP_FRM_SNAPSHOT); 158 } 159 break; 160 } 161 } 162 } 163 // 164 // whether need FD Metadata along with Snapshot frame in ZSL mode 165 if(pme->needFDMetadata(QCAMERA_CH_TYPE_ZSL)){ 166 //Need Face Detection result for snapshot frames 167 //Get the Meta Data frames 168 mm_camera_buf_def_t *pMetaFrame = NULL; 169 for(int i = 0; i < frame->num_bufs; i++){ 170 QCameraStream *pStream = pChannel->getStreamByHandle(frame->bufs[i]->stream_id); 171 if(pStream != NULL){ 172 if(pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)){ 173 pMetaFrame = frame->bufs[i]; //find the metadata 174 break; 175 } 176 } 177 } 178 179 if(pMetaFrame != NULL){ 180 metadata_buffer_t *pMetaData = (metadata_buffer_t *)pMetaFrame->buffer; 181 //send the face detection info 182 uint8_t found = 0; 183 cam_face_detection_data_t faces_data; 184 if (IS_META_AVAILABLE(CAM_INTF_META_FACE_DETECTION, pMetaData)) { 185 faces_data = *((cam_face_detection_data_t *) 186 POINTER_OF_META(CAM_INTF_META_FACE_DETECTION, pMetaData)); 187 found = 1; 188 } 189 faces_data.fd_type = QCAMERA_FD_SNAPSHOT; //HARD CODE here before MCT can support 190 if(!found){ 191 faces_data.num_faces_detected = 0; 192 }else if(faces_data.num_faces_detected > MAX_ROI){ 193 ALOGE("%s: Invalid number of faces %d", 194 __func__, faces_data.num_faces_detected); 195 } 196 qcamera_sm_internal_evt_payload_t *payload = 197 (qcamera_sm_internal_evt_payload_t *)malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 198 if (NULL != payload) { 199 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 200 payload->evt_type = QCAMERA_INTERNAL_EVT_FACE_DETECT_RESULT; 201 payload->faces_data = faces_data; 202 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 203 if (rc != NO_ERROR) { 204 ALOGE("%s: processEvt face_detection_result failed", __func__); 205 free(payload); 206 payload = NULL; 207 } 208 } else { 209 ALOGE("%s: No memory for face_detection_result qcamera_sm_internal_evt_payload_t", __func__); 210 } 211 } 212 } 213 214 property_get("persist.camera.dumpmetadata", value, "0"); 215 int32_t enabled = atoi(value); 216 if (enabled) { 217 mm_camera_buf_def_t *pMetaFrame = NULL; 218 QCameraStream *pStream = NULL; 219 for(int i = 0; i < frame->num_bufs; i++){ 220 pStream = pChannel->getStreamByHandle(frame->bufs[i]->stream_id); 221 if(pStream != NULL){ 222 if(pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)){ 223 pMetaFrame = frame->bufs[i]; 224 if(pMetaFrame != NULL && 225 ((metadata_buffer_t *)pMetaFrame->buffer)->is_tuning_params_valid){ 226 pme->dumpMetadataToFile(pStream, pMetaFrame,(char *)"ZSL_Snapshot"); 227 } 228 break; 229 } 230 } 231 } 232 } 233 234 property_get("persist.camera.zsl_matching", value, "0"); 235 log_matching = atoi(value) > 0 ? true : false; 236 if (log_matching) { 237 CDBG_HIGH("%s : ZSL super buffer contains:", __func__); 238 QCameraStream *pStream = NULL; 239 for (int i = 0; i < frame->num_bufs; i++) { 240 pStream = pChannel->getStreamByHandle(frame->bufs[i]->stream_id); 241 if (pStream != NULL ) { 242 CDBG_HIGH("%s: Buffer with V4L index %d frame index %d of type %d Timestamp: %ld %ld ", 243 __func__, 244 frame->bufs[i]->buf_idx, 245 frame->bufs[i]->frame_idx, 246 pStream->getMyType(), 247 frame->bufs[i]->ts.tv_sec, 248 frame->bufs[i]->ts.tv_nsec); 249 } 250 } 251 } 252 253 // send to postprocessor 254 pme->m_postprocessor.processData(frame); 255 256 CDBG_HIGH("[KPI Perf] %s: X", __func__); 257 } 258 259 /*=========================================================================== 260 * FUNCTION : selectScene 261 * 262 * DESCRIPTION: send a preview callback when a specific selected scene is applied 263 * 264 * PARAMETERS : 265 * @pChannel: Camera channel 266 * @frame : Bundled super buffer 267 * 268 * RETURN : int32_t type of status 269 * NO_ERROR -- success 270 * none-zero failure code 271 *==========================================================================*/ 272 int32_t QCamera2HardwareInterface::selectScene(QCameraChannel *pChannel, 273 mm_camera_super_buf_t *frame) 274 { 275 mm_camera_buf_def_t *pMetaFrame = NULL; 276 QCameraStream *pStream = NULL; 277 cam_scene_mode_type *scene = NULL; 278 cam_scene_mode_type selectedScene = CAM_SCENE_MODE_MAX; 279 int32_t rc = NO_ERROR; 280 281 if ((NULL == frame) || (NULL == pChannel)) { 282 ALOGE("%s: Invalid scene select input", __func__); 283 return BAD_VALUE; 284 } 285 286 selectedScene = mParameters.getSelectedScene(); 287 if (CAM_SCENE_MODE_MAX == selectedScene) { 288 ALOGV("%s: No selected scene", __func__); 289 return NO_ERROR; 290 } 291 292 for(int i = 0; i < frame->num_bufs; i++){ 293 pStream = pChannel->getStreamByHandle(frame->bufs[i]->stream_id); 294 if(pStream != NULL){ 295 if(pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)){ 296 pMetaFrame = frame->bufs[i]; 297 break; 298 } 299 } 300 } 301 302 if (NULL == pMetaFrame) { 303 ALOGE("%s: No metadata buffer found in scene select super buffer", __func__); 304 return NO_INIT; 305 } 306 307 metadata_buffer_t *pMetaData = (metadata_buffer_t *)pMetaFrame->buffer; 308 if (IS_META_AVAILABLE(CAM_INTF_META_CURRENT_SCENE, pMetaData)) { 309 scene = (cam_scene_mode_type *) 310 POINTER_OF_META(CAM_INTF_META_CURRENT_SCENE, pMetaData); 311 } 312 313 if (NULL == scene) { 314 ALOGE("%s: No current scene metadata!", __func__); 315 return NO_INIT; 316 } 317 318 if ((*scene == selectedScene) && 319 (mDataCb != NULL) && 320 (msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_FRAME) > 0)) { 321 mm_camera_buf_def_t *preview_frame = NULL; 322 for(int i = 0; i < frame->num_bufs; i++){ 323 pStream = pChannel->getStreamByHandle(frame->bufs[i]->stream_id); 324 if(pStream != NULL){ 325 if(pStream->isTypeOf(CAM_STREAM_TYPE_PREVIEW)){ 326 preview_frame = frame->bufs[i]; 327 break; 328 } 329 } 330 } 331 if (preview_frame) { 332 QCameraGrallocMemory *memory = (QCameraGrallocMemory *)preview_frame->mem_info; 333 int32_t idx = preview_frame->buf_idx; 334 rc = sendPreviewCallback(pStream, memory, idx); 335 if (NO_ERROR != rc) { 336 ALOGE("%s: Error triggering scene select preview callback", __func__); 337 } else { 338 mParameters.setSelectedScene(CAM_SCENE_MODE_MAX); 339 } 340 } else { 341 ALOGE("%s: No preview buffer found in scene select super buffer", __func__); 342 return NO_INIT; 343 } 344 } 345 346 return rc; 347 } 348 349 /*=========================================================================== 350 * FUNCTION : capture_channel_cb_routine 351 * 352 * DESCRIPTION: helper function to handle snapshot superbuf callback directly from 353 * mm-camera-interface 354 * 355 * PARAMETERS : 356 * @recvd_frame : received super buffer 357 * @userdata : user data ptr 358 * 359 * RETURN : None 360 * 361 * NOTE : recvd_frame will be released after this call by caller, so if 362 * async operation needed for recvd_frame, it's our responsibility 363 * to save a copy for this variable to be used later. 364 *==========================================================================*/ 365 void QCamera2HardwareInterface::capture_channel_cb_routine(mm_camera_super_buf_t *recvd_frame, 366 void *userdata) 367 { 368 char value[PROPERTY_VALUE_MAX]; 369 CDBG_HIGH("[KPI Perf] %s: E PROFILE_YUV_CB_TO_HAL", __func__); 370 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 371 if (pme == NULL || 372 pme->mCameraHandle == NULL || 373 pme->mCameraHandle->camera_handle != recvd_frame->camera_handle){ 374 ALOGE("%s: camera obj not valid", __func__); 375 return; 376 } 377 378 QCameraChannel *pChannel = pme->m_channels[QCAMERA_CH_TYPE_CAPTURE]; 379 if (pChannel == NULL || 380 pChannel->getMyHandle() != recvd_frame->ch_id) { 381 ALOGE("%s: Capture channel doesn't exist, return here", __func__); 382 return; 383 } 384 385 // save a copy for the superbuf 386 mm_camera_super_buf_t* frame = 387 (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t)); 388 if (frame == NULL) { 389 ALOGE("%s: Error allocating memory to save received_frame structure.", __func__); 390 pChannel->bufDone(recvd_frame); 391 return; 392 } 393 *frame = *recvd_frame; 394 395 property_get("persist.camera.dumpmetadata", value, "0"); 396 int32_t enabled = atoi(value); 397 if (enabled) { 398 mm_camera_buf_def_t *pMetaFrame = NULL; 399 QCameraStream *pStream = NULL; 400 for(int i = 0; i < frame->num_bufs; i++){ 401 pStream = pChannel->getStreamByHandle(frame->bufs[i]->stream_id); 402 if(pStream != NULL){ 403 if(pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)){ 404 pMetaFrame = frame->bufs[i]; //find the metadata 405 if(pMetaFrame != NULL && 406 ((metadata_buffer_t *)pMetaFrame->buffer)->is_tuning_params_valid){ 407 pme->dumpMetadataToFile(pStream, pMetaFrame,(char *)"Snapshot"); 408 } 409 break; 410 } 411 } 412 } 413 } 414 415 // Wait on Postproc initialization if needed 416 pme->waitDefferedWork(pme->mReprocJob); 417 418 // send to postprocessor 419 pme->m_postprocessor.processData(frame); 420 421 /* START of test register face image for face authentication */ 422 #ifdef QCOM_TEST_FACE_REGISTER_FACE 423 static uint8_t bRunFaceReg = 1; 424 425 if (bRunFaceReg > 0) { 426 // find snapshot frame 427 QCameraStream *main_stream = NULL; 428 mm_camera_buf_def_t *main_frame = NULL; 429 for (int i = 0; i < recvd_frame->num_bufs; i++) { 430 QCameraStream *pStream = 431 pChannel->getStreamByHandle(recvd_frame->bufs[i]->stream_id); 432 if (pStream != NULL) { 433 if (pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT)) { 434 main_stream = pStream; 435 main_frame = recvd_frame->bufs[i]; 436 break; 437 } 438 } 439 } 440 if (main_stream != NULL && main_frame != NULL) { 441 int32_t faceId = -1; 442 cam_pp_offline_src_config_t config; 443 memset(&config, 0, sizeof(cam_pp_offline_src_config_t)); 444 config.num_of_bufs = 1; 445 main_stream->getFormat(config.input_fmt); 446 main_stream->getFrameDimension(config.input_dim); 447 main_stream->getFrameOffset(config.input_buf_planes.plane_info); 448 CDBG_HIGH("DEBUG: registerFaceImage E"); 449 int32_t rc = pme->registerFaceImage(main_frame->buffer, &config, faceId); 450 CDBG_HIGH("DEBUG: registerFaceImage X, ret=%d, faceId=%d", rc, faceId); 451 bRunFaceReg = 0; 452 } 453 } 454 455 #endif 456 /* END of test register face image for face authentication */ 457 458 CDBG_HIGH("[KPI Perf] %s: X", __func__); 459 } 460 461 /*=========================================================================== 462 * FUNCTION : postproc_channel_cb_routine 463 * 464 * DESCRIPTION: helper function to handle postprocess superbuf callback directly from 465 * mm-camera-interface 466 * 467 * PARAMETERS : 468 * @recvd_frame : received super buffer 469 * @userdata : user data ptr 470 * 471 * RETURN : None 472 * 473 * NOTE : recvd_frame will be released after this call by caller, so if 474 * async operation needed for recvd_frame, it's our responsibility 475 * to save a copy for this variable to be used later. 476 *==========================================================================*/ 477 void QCamera2HardwareInterface::postproc_channel_cb_routine(mm_camera_super_buf_t *recvd_frame, 478 void *userdata) 479 { 480 CDBG_HIGH("[KPI Perf] %s: E", __func__); 481 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 482 if (pme == NULL || 483 pme->mCameraHandle == NULL || 484 pme->mCameraHandle->camera_handle != recvd_frame->camera_handle){ 485 ALOGE("%s: camera obj not valid", __func__); 486 return; 487 } 488 489 // save a copy for the superbuf 490 mm_camera_super_buf_t* frame = 491 (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t)); 492 if (frame == NULL) { 493 ALOGE("%s: Error allocating memory to save received_frame structure.", __func__); 494 return; 495 } 496 *frame = *recvd_frame; 497 498 // send to postprocessor 499 pme->m_postprocessor.processPPData(frame); 500 501 CDBG_HIGH("[KPI Perf] %s: X", __func__); 502 } 503 504 /*=========================================================================== 505 * FUNCTION : preview_stream_cb_routine 506 * 507 * DESCRIPTION: helper function to handle preview frame from preview stream in 508 * normal case with display. 509 * 510 * PARAMETERS : 511 * @super_frame : received super buffer 512 * @stream : stream object 513 * @userdata : user data ptr 514 * 515 * RETURN : None 516 * 517 * NOTE : caller passes the ownership of super_frame, it's our 518 * responsibility to free super_frame once it's done. The new 519 * preview frame will be sent to display, and an older frame 520 * will be dequeued from display and needs to be returned back 521 * to kernel for future use. 522 *==========================================================================*/ 523 void QCamera2HardwareInterface::preview_stream_cb_routine(mm_camera_super_buf_t *super_frame, 524 QCameraStream * stream, 525 void *userdata) 526 { 527 CDBG_HIGH("[KPI Perf] %s : BEGIN", __func__); 528 int err = NO_ERROR; 529 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 530 QCameraGrallocMemory *memory = (QCameraGrallocMemory *)super_frame->bufs[0]->mem_info; 531 532 if (pme == NULL) { 533 ALOGE("%s: Invalid hardware object", __func__); 534 free(super_frame); 535 return; 536 } 537 if (memory == NULL) { 538 ALOGE("%s: Invalid memory object", __func__); 539 free(super_frame); 540 return; 541 } 542 543 mm_camera_buf_def_t *frame = super_frame->bufs[0]; 544 if (NULL == frame) { 545 ALOGE("%s: preview frame is NLUL", __func__); 546 free(super_frame); 547 return; 548 } 549 550 if (!pme->needProcessPreviewFrame()) { 551 ALOGE("%s: preview is not running, no need to process", __func__); 552 stream->bufDone(frame->buf_idx); 553 free(super_frame); 554 return; 555 } 556 557 if (pme->needDebugFps()) { 558 pme->debugShowPreviewFPS(); 559 } 560 561 int idx = frame->buf_idx; 562 pme->dumpFrameToFile(stream, frame, QCAMERA_DUMP_FRM_PREVIEW); 563 564 if(pme->m_bPreviewStarted) { 565 CDBG_HIGH("[KPI Perf] %s : PROFILE_FIRST_PREVIEW_FRAME", __func__); 566 pme->m_bPreviewStarted = false ; 567 } 568 569 // Display the buffer. 570 CDBG("%p displayBuffer %d E", pme, idx); 571 int dequeuedIdx = memory->displayBuffer(idx); 572 if (dequeuedIdx < 0 || dequeuedIdx >= memory->getCnt()) { 573 CDBG_HIGH("%s: Invalid dequeued buffer index %d from display", 574 __func__, dequeuedIdx); 575 } else { 576 // Return dequeued buffer back to driver 577 err = stream->bufDone(dequeuedIdx); 578 if ( err < 0) { 579 ALOGE("stream bufDone failed %d", err); 580 } 581 } 582 583 // Handle preview data callback 584 if (pme->mDataCb != NULL && 585 (pme->msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_FRAME) > 0) && 586 (!pme->mParameters.isSceneSelectionEnabled())) { 587 int32_t rc = pme->sendPreviewCallback(stream, memory, idx); 588 if (NO_ERROR != rc) { 589 ALOGE("%s: Preview callback was not sent succesfully", __func__); 590 } 591 } 592 593 free(super_frame); 594 CDBG_HIGH("[KPI Perf] %s : END", __func__); 595 return; 596 } 597 598 /*=========================================================================== 599 * FUNCTION : sendPreviewCallback 600 * 601 * DESCRIPTION: helper function for triggering preview callbacks 602 * 603 * PARAMETERS : 604 * @stream : stream object 605 * @memory : Gralloc memory allocator 606 * @idx : buffer index 607 * 608 * RETURN : int32_t type of status 609 * NO_ERROR -- success 610 * none-zero failure code 611 *==========================================================================*/ 612 int32_t QCamera2HardwareInterface::sendPreviewCallback(QCameraStream *stream, 613 QCameraGrallocMemory *memory, int32_t idx) 614 { 615 camera_memory_t *previewMem = NULL; 616 camera_memory_t *data = NULL; 617 int previewBufSize; 618 cam_dimension_t preview_dim; 619 cam_format_t previewFmt; 620 int32_t rc = NO_ERROR; 621 622 if ((NULL == stream) || (NULL == memory)) { 623 ALOGE("%s: Invalid preview callback input", __func__); 624 return BAD_VALUE; 625 } 626 627 stream->getFrameDimension(preview_dim); 628 stream->getFormat(previewFmt); 629 630 /* The preview buffer size in the callback should be 631 * (width*height*bytes_per_pixel). As all preview formats we support, 632 * use 12 bits per pixel, buffer size = previewWidth * previewHeight * 3/2. 633 * We need to put a check if some other formats are supported in future. */ 634 if ((previewFmt == CAM_FORMAT_YUV_420_NV21) || 635 (previewFmt == CAM_FORMAT_YUV_420_NV12) || 636 (previewFmt == CAM_FORMAT_YUV_420_YV12)) { 637 if(previewFmt == CAM_FORMAT_YUV_420_YV12) { 638 previewBufSize = ((preview_dim.width+15)/16) * 16 * preview_dim.height + 639 ((preview_dim.width/2+15)/16) * 16* preview_dim.height; 640 } else { 641 previewBufSize = preview_dim.width * preview_dim.height * 3/2; 642 } 643 if(previewBufSize != memory->getSize(idx)) { 644 previewMem = mGetMemory(memory->getFd(idx), 645 previewBufSize, 1, mCallbackCookie); 646 if (!previewMem || !previewMem->data) { 647 ALOGE("%s: mGetMemory failed.\n", __func__); 648 return NO_MEMORY; 649 } else { 650 data = previewMem; 651 } 652 } else 653 data = memory->getMemory(idx, false); 654 } else { 655 data = memory->getMemory(idx, false); 656 ALOGE("%s: Invalid preview format, buffer size in preview callback may be wrong.", 657 __func__); 658 } 659 qcamera_callback_argm_t cbArg; 660 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 661 cbArg.cb_type = QCAMERA_DATA_CALLBACK; 662 cbArg.msg_type = CAMERA_MSG_PREVIEW_FRAME; 663 cbArg.data = data; 664 if ( previewMem ) { 665 cbArg.user_data = previewMem; 666 cbArg.release_cb = releaseCameraMemory; 667 } 668 cbArg.cookie = this; 669 rc = m_cbNotifier.notifyCallback(cbArg); 670 if (rc != NO_ERROR) { 671 ALOGE("%s: fail sending notification", __func__); 672 if (previewMem) { 673 previewMem->release(previewMem); 674 } 675 } 676 677 return rc; 678 } 679 680 /*=========================================================================== 681 * FUNCTION : nodisplay_preview_stream_cb_routine 682 * 683 * DESCRIPTION: helper function to handle preview frame from preview stream in 684 * no-display case 685 * 686 * PARAMETERS : 687 * @super_frame : received super buffer 688 * @stream : stream object 689 * @userdata : user data ptr 690 * 691 * RETURN : None 692 * 693 * NOTE : caller passes the ownership of super_frame, it's our 694 * responsibility to free super_frame once it's done. 695 *==========================================================================*/ 696 void QCamera2HardwareInterface::nodisplay_preview_stream_cb_routine( 697 mm_camera_super_buf_t *super_frame, 698 QCameraStream *stream, 699 void * userdata) 700 { 701 CDBG_HIGH("[KPI Perf] %s E",__func__); 702 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 703 if (pme == NULL || 704 pme->mCameraHandle == NULL || 705 pme->mCameraHandle->camera_handle != super_frame->camera_handle){ 706 ALOGE("%s: camera obj not valid", __func__); 707 // simply free super frame 708 free(super_frame); 709 return; 710 } 711 mm_camera_buf_def_t *frame = super_frame->bufs[0]; 712 if (NULL == frame) { 713 ALOGE("%s: preview frame is NULL", __func__); 714 free(super_frame); 715 return; 716 } 717 718 if (!pme->needProcessPreviewFrame()) { 719 CDBG_HIGH("%s: preview is not running, no need to process", __func__); 720 stream->bufDone(frame->buf_idx); 721 free(super_frame); 722 return; 723 } 724 725 if (pme->needDebugFps()) { 726 pme->debugShowPreviewFPS(); 727 } 728 729 QCameraMemory *previewMemObj = (QCameraMemory *)frame->mem_info; 730 camera_memory_t *preview_mem = NULL; 731 if (previewMemObj != NULL) { 732 preview_mem = previewMemObj->getMemory(frame->buf_idx, false); 733 } 734 if (NULL != previewMemObj && NULL != preview_mem) { 735 pme->dumpFrameToFile(stream, frame, QCAMERA_DUMP_FRM_PREVIEW); 736 737 if (pme->needProcessPreviewFrame() && 738 pme->mDataCb != NULL && 739 pme->msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_FRAME) > 0 ) { 740 qcamera_callback_argm_t cbArg; 741 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 742 cbArg.cb_type = QCAMERA_DATA_CALLBACK; 743 cbArg.msg_type = CAMERA_MSG_PREVIEW_FRAME; 744 cbArg.data = preview_mem; 745 int user_data = frame->buf_idx; 746 cbArg.user_data = ( void * ) user_data; 747 cbArg.cookie = stream; 748 cbArg.release_cb = returnStreamBuffer; 749 int32_t rc = pme->m_cbNotifier.notifyCallback(cbArg); 750 if (rc != NO_ERROR) { 751 ALOGE("%s: fail sending data notify", __func__); 752 stream->bufDone(frame->buf_idx); 753 } 754 } else { 755 stream->bufDone(frame->buf_idx); 756 } 757 } 758 free(super_frame); 759 CDBG_HIGH("[KPI Perf] %s X",__func__); 760 } 761 762 /*=========================================================================== 763 * FUNCTION : rdi_mode_stream_cb_routine 764 * 765 * DESCRIPTION: helper function to handle RDI frame from preview stream in 766 * rdi mode case 767 * 768 * PARAMETERS : 769 * @super_frame : received super buffer 770 * @stream : stream object 771 * @userdata : user data ptr 772 * 773 * RETURN : None 774 * 775 * NOTE : caller passes the ownership of super_frame, it's our 776 * responsibility to free super_frame once it's done. 777 *==========================================================================*/ 778 void QCamera2HardwareInterface::rdi_mode_stream_cb_routine( 779 mm_camera_super_buf_t *super_frame, 780 QCameraStream *stream, 781 void * userdata) 782 { 783 CDBG_HIGH("RDI_DEBUG %s[%d]: Enter", __func__, __LINE__); 784 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 785 if (pme == NULL || 786 pme->mCameraHandle == NULL || 787 pme->mCameraHandle->camera_handle != super_frame->camera_handle){ 788 ALOGE("%s: camera obj not valid", __func__); 789 free(super_frame); 790 return; 791 } 792 mm_camera_buf_def_t *frame = super_frame->bufs[0]; 793 if (NULL == frame) { 794 ALOGE("%s: preview frame is NLUL", __func__); 795 goto end; 796 } 797 if (!pme->needProcessPreviewFrame()) { 798 ALOGE("%s: preview is not running, no need to process", __func__); 799 stream->bufDone(frame->buf_idx); 800 goto end; 801 } 802 if (pme->needDebugFps()) { 803 pme->debugShowPreviewFPS(); 804 } 805 // Non-secure Mode 806 if (!pme->isSecureMode()) { 807 QCameraMemory *previewMemObj = (QCameraMemory *)frame->mem_info; 808 if (NULL == previewMemObj) { 809 ALOGE("%s: previewMemObj is NULL", __func__); 810 stream->bufDone(frame->buf_idx); 811 goto end; 812 } 813 814 camera_memory_t *preview_mem = previewMemObj->getMemory(frame->buf_idx, false); 815 if (NULL != preview_mem) { 816 previewMemObj->cleanCache(frame->buf_idx); 817 // Dump RAW frame 818 pme->dumpFrameToFile(stream, frame, QCAMERA_DUMP_FRM_RAW); 819 // Notify Preview callback frame 820 if (pme->needProcessPreviewFrame() && 821 pme->mDataCb != NULL && 822 pme->msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_FRAME) > 0) { 823 qcamera_callback_argm_t cbArg; 824 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 825 cbArg.cb_type = QCAMERA_DATA_CALLBACK; 826 cbArg.msg_type = CAMERA_MSG_PREVIEW_FRAME; 827 cbArg.data = preview_mem; 828 int user_data = frame->buf_idx; 829 cbArg.user_data = (void *)user_data; 830 cbArg.cookie = stream; 831 cbArg.release_cb = returnStreamBuffer; 832 pme->m_cbNotifier.notifyCallback(cbArg); 833 } else { 834 ALOGE("%s: preview_mem is NULL", __func__); 835 stream->bufDone(frame->buf_idx); 836 } 837 } 838 else { 839 ALOGE("%s: preview_mem is NULL", __func__); 840 stream->bufDone(frame->buf_idx); 841 } 842 } else { 843 // Secure Mode 844 // We will do QCAMERA_NOTIFY_CALLBACK and share FD in case of secure mode 845 QCameraMemory *previewMemObj = (QCameraMemory *)frame->mem_info; 846 if (NULL == previewMemObj) { 847 ALOGE("%s: previewMemObj is NULL", __func__); 848 stream->bufDone(frame->buf_idx); 849 goto end; 850 } 851 852 int fd = previewMemObj->getFd(frame->buf_idx); 853 ALOGD("%s: Preview frame fd =%d for index = %d ", __func__, fd, frame->buf_idx); 854 if (pme->needProcessPreviewFrame() && 855 pme->mDataCb != NULL && 856 pme->msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_FRAME) > 0) { 857 // Prepare Callback structure 858 qcamera_callback_argm_t cbArg; 859 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 860 cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK; 861 cbArg.msg_type = CAMERA_MSG_PREVIEW_FRAME; 862 #ifndef VANILLA_HAL 863 cbArg.ext1 = CAMERA_FRAME_DATA_FD; 864 cbArg.ext2 = fd; 865 #endif 866 int user_data = frame->buf_idx; 867 cbArg.user_data = (void *)user_data; 868 cbArg.cookie = stream; 869 cbArg.release_cb = returnStreamBuffer; 870 pme->m_cbNotifier.notifyCallback(cbArg); 871 } else { 872 CDBG_HIGH("%s: No need to process preview frame, return buffer", __func__); 873 stream->bufDone(frame->buf_idx); 874 } 875 } 876 end: 877 free(super_frame); 878 CDBG_HIGH("RDI_DEBUG %s[%d]: Exit", __func__, __LINE__); 879 return; 880 } 881 882 /*=========================================================================== 883 * FUNCTION : postview_stream_cb_routine 884 * 885 * DESCRIPTION: helper function to handle post frame from postview stream 886 * 887 * PARAMETERS : 888 * @super_frame : received super buffer 889 * @stream : stream object 890 * @userdata : user data ptr 891 * 892 * RETURN : None 893 * 894 * NOTE : caller passes the ownership of super_frame, it's our 895 * responsibility to free super_frame once it's done. 896 *==========================================================================*/ 897 void QCamera2HardwareInterface::postview_stream_cb_routine(mm_camera_super_buf_t *super_frame, 898 QCameraStream *stream, 899 void *userdata) 900 { 901 int err = NO_ERROR; 902 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 903 QCameraGrallocMemory *memory = (QCameraGrallocMemory *)super_frame->bufs[0]->mem_info; 904 905 if (pme == NULL) { 906 ALOGE("%s: Invalid hardware object", __func__); 907 free(super_frame); 908 return; 909 } 910 if (memory == NULL) { 911 ALOGE("%s: Invalid memory object", __func__); 912 free(super_frame); 913 return; 914 } 915 916 CDBG_HIGH("[KPI Perf] %s : BEGIN", __func__); 917 918 mm_camera_buf_def_t *frame = super_frame->bufs[0]; 919 if (NULL == frame) { 920 ALOGE("%s: preview frame is NULL", __func__); 921 free(super_frame); 922 return; 923 } 924 925 QCameraMemory *memObj = (QCameraMemory *)frame->mem_info; 926 if (NULL != memObj) { 927 pme->dumpFrameToFile(stream, frame, QCAMERA_DUMP_FRM_THUMBNAIL); 928 } 929 930 // Return buffer back to driver 931 err = stream->bufDone(frame->buf_idx); 932 if ( err < 0) { 933 ALOGE("stream bufDone failed %d", err); 934 } 935 936 free(super_frame); 937 CDBG_HIGH("[KPI Perf] %s : END", __func__); 938 return; 939 } 940 941 /*=========================================================================== 942 * FUNCTION : video_stream_cb_routine 943 * 944 * DESCRIPTION: helper function to handle video frame from video stream 945 * 946 * PARAMETERS : 947 * @super_frame : received super buffer 948 * @stream : stream object 949 * @userdata : user data ptr 950 * 951 * RETURN : None 952 * 953 * NOTE : caller passes the ownership of super_frame, it's our 954 * responsibility to free super_frame once it's done. video 955 * frame will be sent to video encoder. Once video encoder is 956 * done with the video frame, it will call another API 957 * (release_recording_frame) to return the frame back 958 *==========================================================================*/ 959 void QCamera2HardwareInterface::video_stream_cb_routine(mm_camera_super_buf_t *super_frame, 960 QCameraStream *stream, 961 void *userdata) 962 { 963 CDBG_HIGH("[KPI Perf] %s : BEGIN", __func__); 964 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 965 if (pme == NULL || 966 pme->mCameraHandle == NULL || 967 pme->mCameraHandle->camera_handle != super_frame->camera_handle){ 968 ALOGE("%s: camera obj not valid", __func__); 969 // simply free super frame 970 free(super_frame); 971 return; 972 } 973 mm_camera_buf_def_t *frame = super_frame->bufs[0]; 974 975 if (pme->needDebugFps()) { 976 pme->debugShowVideoFPS(); 977 } 978 if(pme->m_bRecordStarted) { 979 CDBG_HIGH("[KPI Perf] %s : PROFILE_FIRST_RECORD_FRAME", __func__); 980 pme->m_bRecordStarted = false ; 981 } 982 CDBG_HIGH("%s: Stream(%d), Timestamp: %ld %ld", 983 __func__, 984 frame->stream_id, 985 frame->ts.tv_sec, 986 frame->ts.tv_nsec); 987 nsecs_t timeStamp; 988 if(pme->mParameters.isAVTimerEnabled() == true) { 989 timeStamp = (nsecs_t)((frame->ts.tv_sec * 1000000LL) + frame->ts.tv_nsec) * 1000; 990 } else { 991 timeStamp = nsecs_t(frame->ts.tv_sec) * 1000000000LL + frame->ts.tv_nsec; 992 } 993 CDBG_HIGH("Send Video frame to services/encoder TimeStamp : %lld", 994 timeStamp); 995 QCameraMemory *videoMemObj = (QCameraMemory *)frame->mem_info; 996 camera_memory_t *video_mem = NULL; 997 if (NULL != videoMemObj) { 998 video_mem = videoMemObj->getMemory(frame->buf_idx, (pme->mStoreMetaDataInFrame > 0)? true : false); 999 } 1000 if (NULL != videoMemObj && NULL != video_mem) { 1001 pme->dumpFrameToFile(stream, frame, QCAMERA_DUMP_FRM_VIDEO); 1002 if ((pme->mDataCbTimestamp != NULL) && 1003 pme->msgTypeEnabledWithLock(CAMERA_MSG_VIDEO_FRAME) > 0) { 1004 qcamera_callback_argm_t cbArg; 1005 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 1006 cbArg.cb_type = QCAMERA_DATA_TIMESTAMP_CALLBACK; 1007 cbArg.msg_type = CAMERA_MSG_VIDEO_FRAME; 1008 cbArg.data = video_mem; 1009 cbArg.timestamp = timeStamp; 1010 int32_t rc = pme->m_cbNotifier.notifyCallback(cbArg); 1011 if (rc != NO_ERROR) { 1012 ALOGE("%s: fail sending data notify", __func__); 1013 stream->bufDone(frame->buf_idx); 1014 } 1015 } 1016 } 1017 free(super_frame); 1018 CDBG_HIGH("[KPI Perf] %s : END", __func__); 1019 } 1020 1021 /*=========================================================================== 1022 * FUNCTION : snapshot_stream_cb_routine 1023 * 1024 * DESCRIPTION: helper function to handle snapshot frame from snapshot stream 1025 * 1026 * PARAMETERS : 1027 * @super_frame : received super buffer 1028 * @stream : stream object 1029 * @userdata : user data ptr 1030 * 1031 * RETURN : None 1032 * 1033 * NOTE : caller passes the ownership of super_frame, it's our 1034 * responsibility to free super_frame once it's done. For 1035 * snapshot, it need to send to postprocessor for jpeg 1036 * encoding, therefore the ownership of super_frame will be 1037 * hand to postprocessor. 1038 *==========================================================================*/ 1039 void QCamera2HardwareInterface::snapshot_stream_cb_routine(mm_camera_super_buf_t *super_frame, 1040 QCameraStream * /*stream*/, 1041 void *userdata) 1042 { 1043 char value[PROPERTY_VALUE_MAX]; 1044 1045 CDBG_HIGH("[KPI Perf] %s: E", __func__); 1046 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 1047 if (pme == NULL || 1048 pme->mCameraHandle == NULL || 1049 pme->mCameraHandle->camera_handle != super_frame->camera_handle){ 1050 ALOGE("%s: camera obj not valid", __func__); 1051 // simply free super frame 1052 free(super_frame); 1053 return; 1054 } 1055 1056 property_get("persist.camera.dumpmetadata", value, "0"); 1057 int32_t enabled = atoi(value); 1058 if (enabled) { 1059 QCameraChannel *pChannel = pme->m_channels[QCAMERA_CH_TYPE_SNAPSHOT]; 1060 if (pChannel == NULL || 1061 pChannel->getMyHandle() != super_frame->ch_id) { 1062 ALOGE("%s: Capture channel doesn't exist, return here", __func__); 1063 return; 1064 } 1065 mm_camera_buf_def_t *pMetaFrame = NULL; 1066 QCameraStream *pStream = NULL; 1067 for(int i = 0; i < super_frame->num_bufs; i++){ 1068 pStream = pChannel->getStreamByHandle(super_frame->bufs[i]->stream_id); 1069 if(pStream != NULL){ 1070 if(pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)){ 1071 pMetaFrame = super_frame->bufs[i]; //find the metadata 1072 if(pMetaFrame != NULL && 1073 ((metadata_buffer_t *)pMetaFrame->buffer)->is_tuning_params_valid){ 1074 pme->dumpMetadataToFile(pStream, pMetaFrame,(char *)"Snapshot"); 1075 } 1076 break; 1077 } 1078 } 1079 } 1080 } 1081 1082 pme->m_postprocessor.processData(super_frame); 1083 1084 CDBG_HIGH("[KPI Perf] %s: X", __func__); 1085 } 1086 1087 /*=========================================================================== 1088 * FUNCTION : raw_stream_cb_routine 1089 * 1090 * DESCRIPTION: helper function to handle raw dump frame from raw stream 1091 * 1092 * PARAMETERS : 1093 * @super_frame : received super buffer 1094 * @stream : stream object 1095 * @userdata : user data ptr 1096 * 1097 * RETURN : None 1098 * 1099 * NOTE : caller passes the ownership of super_frame, it's our 1100 * responsibility to free super_frame once it's done. For raw 1101 * frame, there is no need to send to postprocessor for jpeg 1102 * encoding. this function will play shutter and send the data 1103 * callback to upper layer. Raw frame buffer will be returned 1104 * back to kernel, and frame will be free after use. 1105 *==========================================================================*/ 1106 void QCamera2HardwareInterface::raw_stream_cb_routine(mm_camera_super_buf_t * super_frame, 1107 QCameraStream * /*stream*/, 1108 void * userdata) 1109 { 1110 CDBG_HIGH("[KPI Perf] %s : BEGIN", __func__); 1111 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 1112 if (pme == NULL || 1113 pme->mCameraHandle == NULL || 1114 pme->mCameraHandle->camera_handle != super_frame->camera_handle){ 1115 ALOGE("%s: camera obj not valid", __func__); 1116 // simply free super frame 1117 free(super_frame); 1118 return; 1119 } 1120 1121 pme->m_postprocessor.processRawData(super_frame); 1122 CDBG_HIGH("[KPI Perf] %s : END", __func__); 1123 } 1124 1125 /*=========================================================================== 1126 * FUNCTION : preview_raw_stream_cb_routine 1127 * 1128 * DESCRIPTION: helper function to handle raw frame during standard preview 1129 * 1130 * PARAMETERS : 1131 * @super_frame : received super buffer 1132 * @stream : stream object 1133 * @userdata : user data ptr 1134 * 1135 * RETURN : None 1136 * 1137 * NOTE : caller passes the ownership of super_frame, it's our 1138 * responsibility to free super_frame once it's done. 1139 *==========================================================================*/ 1140 void QCamera2HardwareInterface::preview_raw_stream_cb_routine(mm_camera_super_buf_t * super_frame, 1141 QCameraStream * stream, 1142 void * userdata) 1143 { 1144 CDBG_HIGH("[KPI Perf] %s : BEGIN", __func__); 1145 int i = -1; 1146 char value[PROPERTY_VALUE_MAX]; 1147 bool dump_raw = false; 1148 1149 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 1150 if (pme == NULL || 1151 pme->mCameraHandle == NULL || 1152 pme->mCameraHandle->camera_handle != super_frame->camera_handle){ 1153 ALOGE("%s: camera obj not valid", __func__); 1154 // simply free super frame 1155 free(super_frame); 1156 return; 1157 } 1158 1159 property_get("persist.camera.preview_raw", value, "0"); 1160 dump_raw = atoi(value) > 0 ? true : false; 1161 1162 for ( i= 0 ; i < super_frame->num_bufs ; i++ ) { 1163 if ( super_frame->bufs[i]->stream_type == CAM_STREAM_TYPE_RAW ) { 1164 mm_camera_buf_def_t * raw_frame = super_frame->bufs[i]; 1165 if ( NULL != stream && (dump_raw) ) { 1166 pme->dumpFrameToFile(stream, raw_frame, QCAMERA_DUMP_FRM_RAW); 1167 } 1168 stream->bufDone(super_frame->bufs[i]->buf_idx); 1169 break; 1170 } 1171 } 1172 1173 free(super_frame); 1174 1175 CDBG_HIGH("[KPI Perf] %s : END", __func__); 1176 } 1177 1178 /*=========================================================================== 1179 * FUNCTION : snapshot_raw_stream_cb_routine 1180 * 1181 * DESCRIPTION: helper function to handle raw frame during standard capture 1182 * 1183 * PARAMETERS : 1184 * @super_frame : received super buffer 1185 * @stream : stream object 1186 * @userdata : user data ptr 1187 * 1188 * RETURN : None 1189 * 1190 * NOTE : caller passes the ownership of super_frame, it's our 1191 * responsibility to free super_frame once it's done. 1192 *==========================================================================*/ 1193 void QCamera2HardwareInterface::snapshot_raw_stream_cb_routine(mm_camera_super_buf_t * super_frame, 1194 QCameraStream * stream, 1195 void * userdata) 1196 { 1197 CDBG_HIGH("[KPI Perf] %s : BEGIN", __func__); 1198 int i = -1; 1199 char value[PROPERTY_VALUE_MAX]; 1200 bool dump_raw = false; 1201 1202 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 1203 if (pme == NULL || 1204 pme->mCameraHandle == NULL || 1205 pme->mCameraHandle->camera_handle != super_frame->camera_handle){ 1206 ALOGE("%s: camera obj not valid", __func__); 1207 // simply free super frame 1208 free(super_frame); 1209 return; 1210 } 1211 1212 property_get("persist.camera.snapshot_raw", value, "0"); 1213 dump_raw = atoi(value) > 0 ? true : false; 1214 1215 for ( i= 0 ; i < super_frame->num_bufs ; i++ ) { 1216 if ( super_frame->bufs[i]->stream_type == CAM_STREAM_TYPE_RAW ) { 1217 mm_camera_buf_def_t * raw_frame = super_frame->bufs[i]; 1218 if ( NULL != stream && (dump_raw) ) { 1219 pme->dumpFrameToFile(stream, raw_frame, QCAMERA_DUMP_FRM_RAW); 1220 } 1221 stream->bufDone(super_frame->bufs[i]->buf_idx); 1222 break; 1223 } 1224 } 1225 1226 free(super_frame); 1227 1228 CDBG_HIGH("[KPI Perf] %s : END", __func__); 1229 } 1230 1231 /*=========================================================================== 1232 * FUNCTION : metadata_stream_cb_routine 1233 * 1234 * DESCRIPTION: helper function to handle metadata frame from metadata stream 1235 * 1236 * PARAMETERS : 1237 * @super_frame : received super buffer 1238 * @stream : stream object 1239 * @userdata : user data ptr 1240 * 1241 * RETURN : None 1242 * 1243 * NOTE : caller passes the ownership of super_frame, it's our 1244 * responsibility to free super_frame once it's done. Metadata 1245 * could have valid entries for face detection result or 1246 * histogram statistics information. 1247 *==========================================================================*/ 1248 void QCamera2HardwareInterface::metadata_stream_cb_routine(mm_camera_super_buf_t * super_frame, 1249 QCameraStream * stream, 1250 void * userdata) 1251 { 1252 CDBG("[KPI Perf] %s : BEGIN", __func__); 1253 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 1254 if (pme == NULL || 1255 pme->mCameraHandle == NULL || 1256 pme->mCameraHandle->camera_handle != super_frame->camera_handle){ 1257 ALOGE("%s: camera obj not valid", __func__); 1258 // simply free super frame 1259 free(super_frame); 1260 return; 1261 } 1262 1263 mm_camera_buf_def_t *frame = super_frame->bufs[0]; 1264 metadata_buffer_t *pMetaData = (metadata_buffer_t *)frame->buffer; 1265 if(pme->m_stateMachine.isNonZSLCaptureRunning()&& 1266 !pme->mLongshotEnabled) { 1267 //Make shutter call back in non ZSL mode once raw frame is received from VFE. 1268 pme->playShutter(); 1269 } 1270 1271 if (pMetaData->is_tuning_params_valid && pme->mParameters.getRecordingHintValue() == true) { 1272 //Dump Tuning data for video 1273 pme->dumpMetadataToFile(stream,frame,(char *)"Video"); 1274 } 1275 if (IS_META_AVAILABLE(CAM_INTF_META_HISTOGRAM, pMetaData)) { 1276 cam_hist_stats_t *stats_data = (cam_hist_stats_t *) 1277 POINTER_OF_META(CAM_INTF_META_HISTOGRAM, pMetaData); 1278 // process histogram statistics info 1279 qcamera_sm_internal_evt_payload_t *payload = 1280 (qcamera_sm_internal_evt_payload_t *) 1281 malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 1282 if (NULL != payload) { 1283 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 1284 payload->evt_type = QCAMERA_INTERNAL_EVT_HISTOGRAM_STATS; 1285 payload->stats_data = *stats_data; 1286 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 1287 if (rc != NO_ERROR) { 1288 ALOGE("%s: processEvt histogram failed", __func__); 1289 free(payload); 1290 payload = NULL; 1291 1292 } 1293 } else { 1294 ALOGE("%s: No memory for histogram qcamera_sm_internal_evt_payload_t", __func__); 1295 } 1296 } 1297 if (IS_META_AVAILABLE(CAM_INTF_META_FACE_DETECTION, pMetaData)) { 1298 cam_face_detection_data_t *faces_data = (cam_face_detection_data_t *) 1299 POINTER_OF_META(CAM_INTF_META_FACE_DETECTION, pMetaData); 1300 if (faces_data->num_faces_detected > MAX_ROI) { 1301 ALOGE("%s: Invalid number of faces %d", 1302 __func__, faces_data->num_faces_detected); 1303 } else { 1304 // process face detection result 1305 if (faces_data->num_faces_detected) 1306 ALOGI("[KPI Perf] %s: PROFILE_NUMBER_OF_FACES_DETECTED %d", 1307 __func__,faces_data->num_faces_detected); 1308 faces_data->fd_type = QCAMERA_FD_PREVIEW; //HARD CODE here before MCT can support 1309 qcamera_sm_internal_evt_payload_t *payload = (qcamera_sm_internal_evt_payload_t *) 1310 malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 1311 if (NULL != payload) { 1312 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 1313 payload->evt_type = QCAMERA_INTERNAL_EVT_FACE_DETECT_RESULT; 1314 payload->faces_data = *faces_data; 1315 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 1316 if (rc != NO_ERROR) { 1317 ALOGE("%s: processEvt face detection failed", __func__); 1318 free(payload); 1319 payload = NULL; 1320 } 1321 } else { 1322 ALOGE("%s: No memory for face detect qcamera_sm_internal_evt_payload_t", __func__); 1323 } 1324 } 1325 } 1326 if (IS_META_AVAILABLE(CAM_INTF_META_AUTOFOCUS_DATA, pMetaData)) { 1327 cam_auto_focus_data_t *focus_data = (cam_auto_focus_data_t *) 1328 POINTER_OF_META(CAM_INTF_META_AUTOFOCUS_DATA, pMetaData); 1329 qcamera_sm_internal_evt_payload_t *payload = 1330 (qcamera_sm_internal_evt_payload_t *)malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 1331 if (NULL != payload) { 1332 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 1333 payload->evt_type = QCAMERA_INTERNAL_EVT_FOCUS_UPDATE; 1334 payload->focus_data = *focus_data; 1335 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 1336 if (rc != NO_ERROR) { 1337 ALOGE("%s: processEvt focus failed", __func__); 1338 free(payload); 1339 payload = NULL; 1340 1341 } 1342 } else { 1343 ALOGE("%s: No memory for focus qcamera_sm_internal_evt_payload_t", __func__); 1344 } 1345 } 1346 if (IS_META_AVAILABLE(CAM_INTF_META_CROP_DATA, pMetaData)) { 1347 cam_crop_data_t *crop_data = 1348 (cam_crop_data_t *)POINTER_OF_META(CAM_INTF_META_CROP_DATA, pMetaData); 1349 if (crop_data->num_of_streams > MAX_NUM_STREAMS) { 1350 ALOGE("%s: Invalid num_of_streams %d in crop_data", __func__, 1351 crop_data->num_of_streams); 1352 } else { 1353 qcamera_sm_internal_evt_payload_t *payload = 1354 (qcamera_sm_internal_evt_payload_t *) 1355 malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 1356 if (NULL != payload) { 1357 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 1358 payload->evt_type = QCAMERA_INTERNAL_EVT_CROP_INFO; 1359 payload->crop_data = *crop_data; 1360 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 1361 if (rc != NO_ERROR) { 1362 ALOGE("%s: processEvt crop info failed", __func__); 1363 free(payload); 1364 payload = NULL; 1365 1366 } 1367 } else { 1368 ALOGE("%s: No memory for prep_snapshot qcamera_sm_internal_evt_payload_t", 1369 __func__); 1370 } 1371 } 1372 } 1373 if (IS_META_AVAILABLE(CAM_INTF_META_PREP_SNAPSHOT_DONE, pMetaData)) { 1374 int32_t *prep_snapshot_done_state = 1375 (int32_t *)POINTER_OF_META(CAM_INTF_META_PREP_SNAPSHOT_DONE, pMetaData); 1376 qcamera_sm_internal_evt_payload_t *payload = 1377 (qcamera_sm_internal_evt_payload_t *)malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 1378 if (NULL != payload) { 1379 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 1380 payload->evt_type = QCAMERA_INTERNAL_EVT_PREP_SNAPSHOT_DONE; 1381 payload->prep_snapshot_state = (cam_prep_snapshot_state_t)*prep_snapshot_done_state; 1382 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 1383 if (rc != NO_ERROR) { 1384 ALOGE("%s: processEvt prep_snapshot failed", __func__); 1385 free(payload); 1386 payload = NULL; 1387 1388 } 1389 } else { 1390 ALOGE("%s: No memory for prep_snapshot qcamera_sm_internal_evt_payload_t", __func__); 1391 } 1392 } 1393 if (IS_META_AVAILABLE(CAM_INTF_META_ASD_HDR_SCENE_DATA, pMetaData)) { 1394 cam_asd_hdr_scene_data_t *hdr_scene_data = 1395 (cam_asd_hdr_scene_data_t *)POINTER_OF_META(CAM_INTF_META_ASD_HDR_SCENE_DATA, pMetaData); 1396 CDBG_HIGH("%s: hdr_scene_data: %d %f\n", __func__, 1397 hdr_scene_data->is_hdr_scene, hdr_scene_data->hdr_confidence); 1398 //Handle this HDR meta data only if capture is not in process 1399 if (!pme->m_stateMachine.isCaptureRunning()) { 1400 int32_t rc = pme->processHDRData(*hdr_scene_data); 1401 if (rc != NO_ERROR) { 1402 ALOGE("%s: processHDRData failed", __func__); 1403 } 1404 } 1405 } 1406 if (IS_META_AVAILABLE(CAM_INTF_META_ASD_SCENE_TYPE, pMetaData)) { 1407 int32_t *scene = 1408 (int32_t *)POINTER_OF_META(CAM_INTF_META_ASD_SCENE_TYPE, pMetaData); 1409 qcamera_sm_internal_evt_payload_t *payload = 1410 (qcamera_sm_internal_evt_payload_t *)malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 1411 if (NULL != payload) { 1412 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 1413 payload->evt_type = QCAMERA_INTERNAL_EVT_ASD_UPDATE; 1414 payload->asd_data = (cam_auto_scene_t)*scene; 1415 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 1416 if (rc != NO_ERROR) { 1417 ALOGE("%s: processEvt asd_update failed", __func__); 1418 free(payload); 1419 payload = NULL; 1420 1421 } 1422 } else { 1423 ALOGE("%s: No memory for asd_update qcamera_sm_internal_evt_payload_t", __func__); 1424 } 1425 } 1426 if (IS_META_AVAILABLE(CAM_INTF_META_FLASH_MODE, pMetaData)) { 1427 uint8_t *flash_mode = 1428 (uint8_t *)POINTER_OF_META(CAM_INTF_META_FLASH_MODE, pMetaData); 1429 pme->mExifParams.sensor_params.flash_mode = (cam_flash_mode_t)*flash_mode; 1430 } 1431 if (IS_META_AVAILABLE(CAM_INTF_META_FLASH_STATE, pMetaData)) { 1432 int32_t *flash_state = 1433 (int32_t *)POINTER_OF_META(CAM_INTF_META_FLASH_STATE, pMetaData); 1434 pme->mExifParams.sensor_params.flash_state = (cam_flash_state_t)*flash_state; 1435 } 1436 if (IS_META_AVAILABLE(CAM_INTF_META_LENS_APERTURE, pMetaData)) { 1437 float *aperture_value = 1438 (float *)POINTER_OF_META(CAM_INTF_META_LENS_APERTURE, pMetaData); 1439 pme->mExifParams.sensor_params.aperture_value = *aperture_value; 1440 } 1441 if (IS_META_AVAILABLE(CAM_INTF_META_AEC_INFO, pMetaData)) { 1442 cam_3a_params_t* ae_params = 1443 (cam_3a_params_t*)POINTER_OF_META(CAM_INTF_META_AEC_INFO, pMetaData); 1444 pme->mExifParams.cam_3a_params = *ae_params; 1445 pme->mFlashNeeded = ae_params->flash_needed; 1446 } 1447 if (IS_META_AVAILABLE(CAM_INTF_META_SENSOR_INFO, pMetaData)) { 1448 cam_sensor_params_t* sensor_params = (cam_sensor_params_t*) 1449 POINTER_OF_META(CAM_INTF_META_SENSOR_INFO, pMetaData); 1450 pme->mExifParams.sensor_params = *sensor_params; 1451 } 1452 1453 stream->bufDone(frame->buf_idx); 1454 free(super_frame); 1455 1456 CDBG("[KPI Perf] %s : END", __func__); 1457 } 1458 1459 /*=========================================================================== 1460 * FUNCTION : reprocess_stream_cb_routine 1461 * 1462 * DESCRIPTION: helper function to handle reprocess frame from reprocess stream 1463 (after reprocess, e.g., ZSL snapshot frame after WNR if 1464 * WNR is enabled) 1465 * 1466 * PARAMETERS : 1467 * @super_frame : received super buffer 1468 * @stream : stream object 1469 * @userdata : user data ptr 1470 * 1471 * RETURN : None 1472 * 1473 * NOTE : caller passes the ownership of super_frame, it's our 1474 * responsibility to free super_frame once it's done. In this 1475 * case, reprocessed frame need to be passed to postprocessor 1476 * for jpeg encoding. 1477 *==========================================================================*/ 1478 void QCamera2HardwareInterface::reprocess_stream_cb_routine(mm_camera_super_buf_t * super_frame, 1479 QCameraStream * /*stream*/, 1480 void * userdata) 1481 { 1482 CDBG_HIGH("[KPI Perf] %s: E", __func__); 1483 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 1484 if (pme == NULL || 1485 pme->mCameraHandle == NULL || 1486 pme->mCameraHandle->camera_handle != super_frame->camera_handle){ 1487 ALOGE("%s: camera obj not valid", __func__); 1488 // simply free super frame 1489 free(super_frame); 1490 return; 1491 } 1492 1493 pme->m_postprocessor.processPPData(super_frame); 1494 1495 CDBG_HIGH("[KPI Perf] %s: X", __func__); 1496 } 1497 1498 /*=========================================================================== 1499 * FUNCTION : dumpFrameToFile 1500 * 1501 * DESCRIPTION: helper function to dump jpeg into file for debug purpose. 1502 * 1503 * PARAMETERS : 1504 * @data : data ptr 1505 * @size : length of data buffer 1506 * @index : identifier for data 1507 * 1508 * RETURN : None 1509 *==========================================================================*/ 1510 void QCamera2HardwareInterface::dumpJpegToFile(const void *data, 1511 uint32_t size, 1512 int index) 1513 { 1514 char value[PROPERTY_VALUE_MAX]; 1515 property_get("persist.camera.dumpimg", value, "0"); 1516 int32_t enabled = atoi(value); 1517 int frm_num = 0; 1518 uint32_t skip_mode = 0; 1519 1520 char buf[32]; 1521 cam_dimension_t dim; 1522 memset(buf, 0, sizeof(buf)); 1523 memset(&dim, 0, sizeof(dim)); 1524 1525 if((enabled & QCAMERA_DUMP_FRM_JPEG) && data) { 1526 frm_num = ((enabled & 0xffff0000) >> 16); 1527 if(frm_num == 0) { 1528 frm_num = 10; //default 10 frames 1529 } 1530 if(frm_num > 256) { 1531 frm_num = 256; //256 buffers cycle around 1532 } 1533 skip_mode = ((enabled & 0x0000ff00) >> 8); 1534 if(skip_mode == 0) { 1535 skip_mode = 1; //no-skip 1536 } 1537 1538 if( mDumpSkipCnt % skip_mode == 0) { 1539 if((frm_num == 256) && (mDumpFrmCnt >= frm_num)) { 1540 // reset frame count if cycling 1541 mDumpFrmCnt = 0; 1542 } 1543 if (mDumpFrmCnt >= 0 && mDumpFrmCnt <= frm_num) { 1544 snprintf(buf, sizeof(buf), "/data/%d_%d.jpg", mDumpFrmCnt, index); 1545 1546 int file_fd = open(buf, O_RDWR | O_CREAT, 0777); 1547 if (file_fd > 0) { 1548 int written_len = write(file_fd, data, size); 1549 CDBG_HIGH("%s: written number of bytes %d\n", 1550 __func__, written_len); 1551 close(file_fd); 1552 } else { 1553 ALOGE("%s: fail t open file for image dumping", __func__); 1554 } 1555 mDumpFrmCnt++; 1556 } 1557 } 1558 mDumpSkipCnt++; 1559 } 1560 } 1561 1562 1563 void QCamera2HardwareInterface::dumpMetadataToFile(QCameraStream *stream, 1564 mm_camera_buf_def_t *frame,char *type) 1565 { 1566 char value[PROPERTY_VALUE_MAX]; 1567 int frm_num = 0; 1568 metadata_buffer_t *metadata = (metadata_buffer_t *)frame->buffer; 1569 property_get("persist.camera.dumpmetadata", value, "0"); 1570 int32_t enabled = atoi(value); 1571 if (stream == NULL) { 1572 CDBG_HIGH("No op"); 1573 return; 1574 } 1575 1576 int mDumpFrmCnt = stream->mDumpMetaFrame; 1577 if(enabled){ 1578 frm_num = ((enabled & 0xffff0000) >> 16); 1579 if(frm_num == 0) { 1580 frm_num = 10; //default 10 frames 1581 } 1582 if(frm_num > 256) { 1583 frm_num = 256; //256 buffers cycle around 1584 } 1585 if((frm_num == 256) && (mDumpFrmCnt >= frm_num)) { 1586 // reset frame count if cycling 1587 mDumpFrmCnt = 0; 1588 } 1589 CDBG_HIGH("mDumpFrmCnt= %d, frm_num = %d",mDumpFrmCnt,frm_num); 1590 if (mDumpFrmCnt >= 0 && mDumpFrmCnt < frm_num) { 1591 char timeBuf[128]; 1592 char buf[32]; 1593 memset(buf, 0, sizeof(buf)); 1594 memset(timeBuf, 0, sizeof(timeBuf)); 1595 time_t current_time; 1596 struct tm * timeinfo; 1597 time (¤t_time); 1598 timeinfo = localtime (¤t_time); 1599 strftime (timeBuf, sizeof(timeBuf),"/data/%Y%m%d%H%M%S", timeinfo); 1600 String8 filePath(timeBuf); 1601 snprintf(buf, sizeof(buf), "%dm_%s_%d.bin", 1602 mDumpFrmCnt,type,frame->frame_idx); 1603 filePath.append(buf); 1604 int file_fd = open(filePath.string(), O_RDWR | O_CREAT, 0777); 1605 if (file_fd > 0) { 1606 int written_len = 0; 1607 metadata->tuning_params.tuning_data_version = TUNING_DATA_VERSION; 1608 void *data = (void *)((uint8_t *)&metadata->tuning_params.tuning_data_version); 1609 written_len += write(file_fd, data, sizeof(uint32_t)); 1610 data = (void *)((uint8_t *)&metadata->tuning_params.tuning_sensor_data_size); 1611 CDBG_HIGH("tuning_sensor_data_size %d",(int)(*(int *)data)); 1612 written_len += write(file_fd, data, sizeof(uint32_t)); 1613 data = (void *)((uint8_t *)&metadata->tuning_params.tuning_vfe_data_size); 1614 CDBG_HIGH("tuning_vfe_data_size %d",(int)(*(int *)data)); 1615 written_len += write(file_fd, data, sizeof(uint32_t)); 1616 data = (void *)((uint8_t *)&metadata->tuning_params.tuning_cpp_data_size); 1617 CDBG_HIGH("tuning_cpp_data_size %d",(int)(*(int *)data)); 1618 written_len += write(file_fd, data, sizeof(uint32_t)); 1619 data = (void *)((uint8_t *)&metadata->tuning_params.tuning_cac_data_size); 1620 CDBG_HIGH("tuning_cac_data_size %d",(int)(*(int *)data)); 1621 written_len += write(file_fd, data, sizeof(uint32_t)); 1622 int total_size = metadata->tuning_params.tuning_sensor_data_size; 1623 data = (void *)((uint8_t *)&metadata->tuning_params.data); 1624 written_len += write(file_fd, data, total_size); 1625 total_size = metadata->tuning_params.tuning_vfe_data_size; 1626 data = (void *)((uint8_t *)&metadata->tuning_params.data[TUNING_VFE_DATA_OFFSET]); 1627 written_len += write(file_fd, data, total_size); 1628 total_size = metadata->tuning_params.tuning_cpp_data_size; 1629 data = (void *)((uint8_t *)&metadata->tuning_params.data[TUNING_CPP_DATA_OFFSET]); 1630 written_len += write(file_fd, data, total_size); 1631 total_size = metadata->tuning_params.tuning_cac_data_size; 1632 data = (void *)((uint8_t *)&metadata->tuning_params.data[TUNING_CAC_DATA_OFFSET]); 1633 written_len += write(file_fd, data, total_size); 1634 close(file_fd); 1635 }else { 1636 ALOGE("%s: fail t open file for image dumping", __func__); 1637 } 1638 mDumpFrmCnt++; 1639 } 1640 } 1641 stream->mDumpMetaFrame = mDumpFrmCnt; 1642 } 1643 /*=========================================================================== 1644 * FUNCTION : dumpFrameToFile 1645 * 1646 * DESCRIPTION: helper function to dump frame into file for debug purpose. 1647 * 1648 * PARAMETERS : 1649 * @data : data ptr 1650 * @size : length of data buffer 1651 * @index : identifier for data 1652 * @dump_type : type of the frame to be dumped. Only such 1653 * dump type is enabled, the frame will be 1654 * dumped into a file. 1655 * 1656 * RETURN : None 1657 *==========================================================================*/ 1658 void QCamera2HardwareInterface::dumpFrameToFile(QCameraStream *stream, 1659 mm_camera_buf_def_t *frame, 1660 int dump_type) 1661 { 1662 char value[PROPERTY_VALUE_MAX]; 1663 property_get("persist.camera.dumpimg", value, "0"); 1664 int32_t enabled = atoi(value); 1665 int frm_num = 0; 1666 uint32_t skip_mode = 0; 1667 int mDumpFrmCnt = stream->mDumpFrame; 1668 1669 if(enabled & QCAMERA_DUMP_FRM_MASK_ALL) { 1670 if((enabled & dump_type) && stream && frame) { 1671 frm_num = ((enabled & 0xffff0000) >> 16); 1672 if(frm_num == 0) { 1673 frm_num = 10; //default 10 frames 1674 } 1675 if(frm_num > 256) { 1676 frm_num = 256; //256 buffers cycle around 1677 } 1678 skip_mode = ((enabled & 0x0000ff00) >> 8); 1679 if(skip_mode == 0) { 1680 skip_mode = 1; //no-skip 1681 } 1682 if(stream->mDumpSkipCnt == 0) 1683 stream->mDumpSkipCnt = 1; 1684 1685 if( stream->mDumpSkipCnt % skip_mode == 0) { 1686 if((frm_num == 256) && (mDumpFrmCnt >= frm_num)) { 1687 // reset frame count if cycling 1688 mDumpFrmCnt = 0; 1689 } 1690 if (mDumpFrmCnt >= 0 && mDumpFrmCnt <= frm_num) { 1691 char buf[32]; 1692 char timeBuf[128]; 1693 time_t current_time; 1694 struct tm * timeinfo; 1695 1696 1697 time (¤t_time); 1698 timeinfo = localtime (¤t_time); 1699 memset(buf, 0, sizeof(buf)); 1700 1701 cam_dimension_t dim; 1702 memset(&dim, 0, sizeof(dim)); 1703 stream->getFrameDimension(dim); 1704 1705 cam_frame_len_offset_t offset; 1706 memset(&offset, 0, sizeof(cam_frame_len_offset_t)); 1707 stream->getFrameOffset(offset); 1708 1709 strftime (timeBuf, sizeof(timeBuf),"/data/%Y%m%d%H%M%S", timeinfo); 1710 String8 filePath(timeBuf); 1711 switch (dump_type) { 1712 case QCAMERA_DUMP_FRM_PREVIEW: 1713 { 1714 snprintf(buf, sizeof(buf), "%dp_%dx%d_%d.yuv", 1715 mDumpFrmCnt, dim.width, dim.height, frame->frame_idx); 1716 } 1717 break; 1718 case QCAMERA_DUMP_FRM_THUMBNAIL: 1719 { 1720 snprintf(buf, sizeof(buf), "%dt_%dx%d_%d.yuv", 1721 mDumpFrmCnt, dim.width, dim.height, frame->frame_idx); 1722 } 1723 break; 1724 case QCAMERA_DUMP_FRM_SNAPSHOT: 1725 { 1726 mParameters.getStreamDimension(CAM_STREAM_TYPE_SNAPSHOT, dim); 1727 snprintf(buf, sizeof(buf), "%ds_%dx%d_%d.yuv", 1728 mDumpFrmCnt, 1729 dim.width, 1730 dim.height, 1731 frame->frame_idx); 1732 } 1733 break; 1734 case QCAMERA_DUMP_FRM_VIDEO: 1735 { 1736 snprintf(buf, sizeof(buf), "%dv_%dx%d_%d.yuv", 1737 mDumpFrmCnt, dim.width, dim.height, frame->frame_idx); 1738 } 1739 break; 1740 case QCAMERA_DUMP_FRM_RAW: 1741 { 1742 mParameters.getStreamDimension(CAM_STREAM_TYPE_RAW, dim); 1743 snprintf(buf, sizeof(buf), "%dr_%dx%d_%d.raw", 1744 mDumpFrmCnt, 1745 dim.width, 1746 dim.height, 1747 frame->frame_idx); 1748 } 1749 break; 1750 case QCAMERA_DUMP_FRM_JPEG: 1751 { 1752 mParameters.getStreamDimension(CAM_STREAM_TYPE_SNAPSHOT, dim); 1753 snprintf(buf, sizeof(buf), "%dj_%dx%d_%d.yuv", 1754 mDumpFrmCnt, 1755 dim.width, 1756 dim.height, 1757 frame->frame_idx); 1758 } 1759 break; 1760 default: 1761 ALOGE("%s: Not supported for dumping stream type %d", 1762 __func__, dump_type); 1763 return; 1764 } 1765 1766 filePath.append(buf); 1767 int file_fd = open(filePath.string(), O_RDWR | O_CREAT, 0777); 1768 if (file_fd > 0) { 1769 void *data = NULL; 1770 int written_len = 0; 1771 1772 for (int i = 0; i < offset.num_planes; i++) { 1773 uint32_t index = offset.mp[i].offset; 1774 if (i > 0) { 1775 index += offset.mp[i-1].len; 1776 } 1777 for (int j = 0; j < offset.mp[i].height; j++) { 1778 data = (void *)((uint8_t *)frame->buffer + index); 1779 written_len += write(file_fd, data, offset.mp[i].width); 1780 index += offset.mp[i].stride; 1781 } 1782 } 1783 1784 CDBG_HIGH("%s: written number of bytes %d\n", 1785 __func__, written_len); 1786 close(file_fd); 1787 } else { 1788 ALOGE("%s: fail t open file for image dumping", __func__); 1789 } 1790 mDumpFrmCnt++; 1791 } 1792 } 1793 stream->mDumpSkipCnt++; 1794 } 1795 } else { 1796 mDumpFrmCnt = 0; 1797 } 1798 stream->mDumpFrame = mDumpFrmCnt; 1799 } 1800 1801 /*=========================================================================== 1802 * FUNCTION : debugShowVideoFPS 1803 * 1804 * DESCRIPTION: helper function to log video frame FPS for debug purpose. 1805 * 1806 * PARAMETERS : None 1807 * 1808 * RETURN : None 1809 *==========================================================================*/ 1810 void QCamera2HardwareInterface::debugShowVideoFPS() 1811 { 1812 static int n_vFrameCount = 0; 1813 static int n_vLastFrameCount = 0; 1814 static nsecs_t n_vLastFpsTime = 0; 1815 static float n_vFps = 0; 1816 n_vFrameCount++; 1817 nsecs_t now = systemTime(); 1818 nsecs_t diff = now - n_vLastFpsTime; 1819 if (diff > ms2ns(250)) { 1820 n_vFps = ((n_vFrameCount - n_vLastFrameCount) * float(s2ns(1))) / diff; 1821 CDBG_HIGH("Video Frames Per Second: %.4f", n_vFps); 1822 n_vLastFpsTime = now; 1823 n_vLastFrameCount = n_vFrameCount; 1824 } 1825 } 1826 1827 /*=========================================================================== 1828 * FUNCTION : debugShowPreviewFPS 1829 * 1830 * DESCRIPTION: helper function to log preview frame FPS for debug purpose. 1831 * 1832 * PARAMETERS : None 1833 * 1834 * RETURN : None 1835 *==========================================================================*/ 1836 void QCamera2HardwareInterface::debugShowPreviewFPS() 1837 { 1838 static int n_pFrameCount = 0; 1839 static int n_pLastFrameCount = 0; 1840 static nsecs_t n_pLastFpsTime = 0; 1841 static float n_pFps = 0; 1842 n_pFrameCount++; 1843 nsecs_t now = systemTime(); 1844 nsecs_t diff = now - n_pLastFpsTime; 1845 if (diff > ms2ns(250)) { 1846 n_pFps = ((n_pFrameCount - n_pLastFrameCount) * float(s2ns(1))) / diff; 1847 CDBG_HIGH("[KPI Perf] %s: PROFILE_PREVIEW_FRAMES_PER_SECOND : %.4f", 1848 __func__, n_pFps); 1849 n_pLastFpsTime = now; 1850 n_pLastFrameCount = n_pFrameCount; 1851 } 1852 } 1853 1854 /*=========================================================================== 1855 * FUNCTION : ~QCameraCbNotifier 1856 * 1857 * DESCRIPTION: Destructor for exiting the callback context. 1858 * 1859 * PARAMETERS : None 1860 * 1861 * RETURN : None 1862 *==========================================================================*/ 1863 QCameraCbNotifier::~QCameraCbNotifier() 1864 { 1865 } 1866 1867 /*=========================================================================== 1868 * FUNCTION : exit 1869 * 1870 * DESCRIPTION: exit notify thread. 1871 * 1872 * PARAMETERS : None 1873 * 1874 * RETURN : None 1875 *==========================================================================*/ 1876 void QCameraCbNotifier::exit() 1877 { 1878 mActive = false; 1879 mProcTh.exit(); 1880 } 1881 1882 /*=========================================================================== 1883 * FUNCTION : releaseNotifications 1884 * 1885 * DESCRIPTION: callback for releasing data stored in the callback queue. 1886 * 1887 * PARAMETERS : 1888 * @data : data to be released 1889 * @user_data : context data 1890 * 1891 * RETURN : None 1892 *==========================================================================*/ 1893 void QCameraCbNotifier::releaseNotifications(void *data, void *user_data) 1894 { 1895 qcamera_callback_argm_t *arg = ( qcamera_callback_argm_t * ) data; 1896 1897 if ( ( NULL != arg ) && ( NULL != user_data ) ) { 1898 if ( arg->release_cb ) { 1899 arg->release_cb(arg->user_data, arg->cookie, FAILED_TRANSACTION); 1900 } 1901 } 1902 } 1903 1904 /*=========================================================================== 1905 * FUNCTION : matchSnapshotNotifications 1906 * 1907 * DESCRIPTION: matches snapshot data callbacks 1908 * 1909 * PARAMETERS : 1910 * @data : data to match 1911 * @user_data : context data 1912 * 1913 * RETURN : bool match 1914 * true - match found 1915 * false- match not found 1916 *==========================================================================*/ 1917 bool QCameraCbNotifier::matchSnapshotNotifications(void *data, 1918 void */*user_data*/) 1919 { 1920 qcamera_callback_argm_t *arg = ( qcamera_callback_argm_t * ) data; 1921 if ( NULL != arg ) { 1922 if ( QCAMERA_DATA_SNAPSHOT_CALLBACK == arg->cb_type ) { 1923 return true; 1924 } 1925 } 1926 1927 return false; 1928 } 1929 1930 /*=========================================================================== 1931 * FUNCTION : cbNotifyRoutine 1932 * 1933 * DESCRIPTION: callback thread which interfaces with the upper layers 1934 * given input commands. 1935 * 1936 * PARAMETERS : 1937 * @data : context data 1938 * 1939 * RETURN : None 1940 *==========================================================================*/ 1941 void * QCameraCbNotifier::cbNotifyRoutine(void * data) 1942 { 1943 int running = 1; 1944 int ret; 1945 QCameraCbNotifier *pme = (QCameraCbNotifier *)data; 1946 QCameraCmdThread *cmdThread = &pme->mProcTh; 1947 uint8_t isSnapshotActive = FALSE; 1948 bool longShotEnabled = false; 1949 uint32_t numOfSnapshotExpected = 0; 1950 uint32_t numOfSnapshotRcvd = 0; 1951 int32_t cbStatus = NO_ERROR; 1952 1953 CDBG("%s: E", __func__); 1954 do { 1955 do { 1956 ret = cam_sem_wait(&cmdThread->cmd_sem); 1957 if (ret != 0 && errno != EINVAL) { 1958 CDBG("%s: cam_sem_wait error (%s)", 1959 __func__, strerror(errno)); 1960 return NULL; 1961 } 1962 } while (ret != 0); 1963 1964 camera_cmd_type_t cmd = cmdThread->getCmd(); 1965 CDBG("%s: get cmd %d", __func__, cmd); 1966 switch (cmd) { 1967 case CAMERA_CMD_TYPE_START_DATA_PROC: 1968 { 1969 isSnapshotActive = TRUE; 1970 numOfSnapshotExpected = pme->mParent->numOfSnapshotsExpected(); 1971 longShotEnabled = pme->mParent->isLongshotEnabled(); 1972 CDBG_HIGH("%s: Num Snapshots Expected = %d", 1973 __func__, numOfSnapshotExpected); 1974 numOfSnapshotRcvd = 0; 1975 } 1976 break; 1977 case CAMERA_CMD_TYPE_STOP_DATA_PROC: 1978 { 1979 pme->mDataQ.flushNodes(matchSnapshotNotifications); 1980 isSnapshotActive = FALSE; 1981 1982 numOfSnapshotExpected = 0; 1983 numOfSnapshotRcvd = 0; 1984 } 1985 break; 1986 case CAMERA_CMD_TYPE_DO_NEXT_JOB: 1987 { 1988 qcamera_callback_argm_t *cb = 1989 (qcamera_callback_argm_t *)pme->mDataQ.dequeue(); 1990 cbStatus = NO_ERROR; 1991 if (NULL != cb) { 1992 CDBG("%s: cb type %d received", 1993 __func__, 1994 cb->cb_type); 1995 1996 if (pme->mParent->msgTypeEnabledWithLock(cb->msg_type)) { 1997 switch (cb->cb_type) { 1998 case QCAMERA_NOTIFY_CALLBACK: 1999 { 2000 if (cb->msg_type == CAMERA_MSG_FOCUS) { 2001 CDBG_HIGH("[KPI Perf] %s : PROFILE_SENDING_FOCUS_EVT_TO APP", 2002 __func__); 2003 } 2004 if (pme->mNotifyCb) { 2005 pme->mNotifyCb(cb->msg_type, 2006 cb->ext1, 2007 cb->ext2, 2008 pme->mCallbackCookie); 2009 } else { 2010 ALOGE("%s : notify callback not set!", 2011 __func__); 2012 } 2013 } 2014 break; 2015 case QCAMERA_DATA_CALLBACK: 2016 { 2017 if (pme->mDataCb) { 2018 pme->mDataCb(cb->msg_type, 2019 cb->data, 2020 cb->index, 2021 cb->metadata, 2022 pme->mCallbackCookie); 2023 } else { 2024 ALOGE("%s : data callback not set!", 2025 __func__); 2026 } 2027 } 2028 break; 2029 case QCAMERA_DATA_TIMESTAMP_CALLBACK: 2030 { 2031 if(pme->mDataCbTimestamp) { 2032 pme->mDataCbTimestamp(cb->timestamp, 2033 cb->msg_type, 2034 cb->data, 2035 cb->index, 2036 pme->mCallbackCookie); 2037 } else { 2038 ALOGE("%s:data cb with tmp not set!", 2039 __func__); 2040 } 2041 } 2042 break; 2043 case QCAMERA_DATA_SNAPSHOT_CALLBACK: 2044 { 2045 if (TRUE == isSnapshotActive && pme->mDataCb ) { 2046 if (!longShotEnabled) { 2047 numOfSnapshotRcvd++; 2048 CDBG_HIGH("%s: [ZSL Retro] Num Snapshots Received = %d", __func__, 2049 numOfSnapshotRcvd); 2050 if (numOfSnapshotExpected > 0 && 2051 (numOfSnapshotExpected == numOfSnapshotRcvd)) { 2052 CDBG_HIGH("%s: [ZSL Retro] Expected snapshot received = %d", 2053 __func__, numOfSnapshotRcvd); 2054 // notify HWI that snapshot is done 2055 pme->mParent->processSyncEvt(QCAMERA_SM_EVT_SNAPSHOT_DONE, 2056 NULL); 2057 } 2058 } 2059 pme->mDataCb(cb->msg_type, 2060 cb->data, 2061 cb->index, 2062 cb->metadata, 2063 pme->mCallbackCookie); 2064 } 2065 } 2066 break; 2067 default: 2068 { 2069 ALOGE("%s : invalid cb type %d", 2070 __func__, 2071 cb->cb_type); 2072 cbStatus = BAD_VALUE; 2073 } 2074 break; 2075 }; 2076 } else { 2077 ALOGE("%s : cb message type %d not enabled!", 2078 __func__, 2079 cb->msg_type); 2080 cbStatus = INVALID_OPERATION; 2081 } 2082 if ( cb->release_cb ) { 2083 cb->release_cb(cb->user_data, cb->cookie, cbStatus); 2084 } 2085 delete cb; 2086 } else { 2087 ALOGE("%s: invalid cb type passed", __func__); 2088 } 2089 } 2090 break; 2091 case CAMERA_CMD_TYPE_EXIT: 2092 { 2093 running = 0; 2094 pme->mDataQ.flush(); 2095 } 2096 break; 2097 default: 2098 break; 2099 } 2100 } while (running); 2101 CDBG("%s: X", __func__); 2102 2103 return NULL; 2104 } 2105 2106 /*=========================================================================== 2107 * FUNCTION : notifyCallback 2108 * 2109 * DESCRIPTION: Enqueus pending callback notifications for the upper layers. 2110 * 2111 * PARAMETERS : 2112 * @cbArgs : callback arguments 2113 * 2114 * RETURN : int32_t type of status 2115 * NO_ERROR -- success 2116 * none-zero failure code 2117 *==========================================================================*/ 2118 int32_t QCameraCbNotifier::notifyCallback(qcamera_callback_argm_t &cbArgs) 2119 { 2120 if (!mActive) { 2121 ALOGE("%s: notify thread is not active", __func__); 2122 return UNKNOWN_ERROR; 2123 } 2124 2125 qcamera_callback_argm_t *cbArg = new qcamera_callback_argm_t(); 2126 if (NULL == cbArg) { 2127 ALOGE("%s: no mem for qcamera_callback_argm_t", __func__); 2128 return NO_MEMORY; 2129 } 2130 memset(cbArg, 0, sizeof(qcamera_callback_argm_t)); 2131 *cbArg = cbArgs; 2132 2133 if (mDataQ.enqueue((void *)cbArg)) { 2134 return mProcTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE); 2135 } else { 2136 ALOGE("%s: Error adding cb data into queue", __func__); 2137 delete cbArg; 2138 return UNKNOWN_ERROR; 2139 } 2140 } 2141 2142 /*=========================================================================== 2143 * FUNCTION : setCallbacks 2144 * 2145 * DESCRIPTION: Initializes the callback functions, which would be used for 2146 * communication with the upper layers and launches the callback 2147 * context in which the callbacks will occur. 2148 * 2149 * PARAMETERS : 2150 * @notifyCb : notification callback 2151 * @dataCb : data callback 2152 * @dataCbTimestamp : data with timestamp callback 2153 * @callbackCookie : callback context data 2154 * 2155 * RETURN : None 2156 *==========================================================================*/ 2157 void QCameraCbNotifier::setCallbacks(camera_notify_callback notifyCb, 2158 camera_data_callback dataCb, 2159 camera_data_timestamp_callback dataCbTimestamp, 2160 void *callbackCookie) 2161 { 2162 if ( ( NULL == mNotifyCb ) && 2163 ( NULL == mDataCb ) && 2164 ( NULL == mDataCbTimestamp ) && 2165 ( NULL == mCallbackCookie ) ) { 2166 mNotifyCb = notifyCb; 2167 mDataCb = dataCb; 2168 mDataCbTimestamp = dataCbTimestamp; 2169 mCallbackCookie = callbackCookie; 2170 mActive = true; 2171 mProcTh.launch(cbNotifyRoutine, this); 2172 } else { 2173 ALOGE("%s : Camera callback notifier already initialized!", 2174 __func__); 2175 } 2176 } 2177 2178 /*=========================================================================== 2179 * FUNCTION : startSnapshots 2180 * 2181 * DESCRIPTION: Enables snapshot mode 2182 * 2183 * PARAMETERS : None 2184 * 2185 * RETURN : int32_t type of status 2186 * NO_ERROR -- success 2187 * none-zero failure code 2188 *==========================================================================*/ 2189 int32_t QCameraCbNotifier::startSnapshots() 2190 { 2191 return mProcTh.sendCmd(CAMERA_CMD_TYPE_START_DATA_PROC, FALSE, TRUE); 2192 } 2193 2194 /*=========================================================================== 2195 * FUNCTION : stopSnapshots 2196 * 2197 * DESCRIPTION: Disables snapshot processing mode 2198 * 2199 * PARAMETERS : None 2200 * 2201 * RETURN : None 2202 *==========================================================================*/ 2203 void QCameraCbNotifier::stopSnapshots() 2204 { 2205 mProcTh.sendCmd(CAMERA_CMD_TYPE_STOP_DATA_PROC, FALSE, TRUE); 2206 } 2207 2208 }; // namespace qcamera 2209