1 /* Copyright (c) 2012-2015, 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 #define ATRACE_TAG ATRACE_TAG_CAMERA 32 33 #include <time.h> 34 #include <fcntl.h> 35 #include <sys/stat.h> 36 #include <utils/Errors.h> 37 #include <utils/Trace.h> 38 #include <utils/Timers.h> 39 #include <QComOMXMetadata.h> 40 #include "QCamera2HWI.h" 41 42 namespace qcamera { 43 44 /*=========================================================================== 45 * FUNCTION : zsl_channel_cb 46 * 47 * DESCRIPTION: helper function to handle ZSL superbuf callback directly from 48 * mm-camera-interface 49 * 50 * PARAMETERS : 51 * @recvd_frame : received super buffer 52 * @userdata : user data ptr 53 * 54 * RETURN : None 55 * 56 * NOTE : recvd_frame will be released after this call by caller, so if 57 * async operation needed for recvd_frame, it's our responsibility 58 * to save a copy for this variable to be used later. 59 *==========================================================================*/ 60 void QCamera2HardwareInterface::zsl_channel_cb(mm_camera_super_buf_t *recvd_frame, 61 void *userdata) 62 { 63 ATRACE_CALL(); 64 CDBG_HIGH("[KPI Perf] %s: E",__func__); 65 char value[PROPERTY_VALUE_MAX]; 66 bool dump_raw = false; 67 bool dump_yuv = false; 68 bool log_matching = false; 69 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 70 if (pme == NULL || 71 pme->mCameraHandle == NULL || 72 pme->mCameraHandle->camera_handle != recvd_frame->camera_handle){ 73 ALOGE("%s: camera obj not valid", __func__); 74 return; 75 } 76 77 QCameraChannel *pChannel = pme->m_channels[QCAMERA_CH_TYPE_ZSL]; 78 if (pChannel == NULL || 79 pChannel->getMyHandle() != recvd_frame->ch_id) { 80 ALOGE("%s: ZSL channel doesn't exist, return here", __func__); 81 return; 82 } 83 84 if(pme->mParameters.isSceneSelectionEnabled() && 85 !pme->m_stateMachine.isCaptureRunning()) { 86 pme->selectScene(pChannel, recvd_frame); 87 pChannel->bufDone(recvd_frame); 88 return; 89 } 90 91 CDBG_HIGH("%s: [ZSL Retro] Frame CB Unlock : %d, is AEC Locked: %d", 92 __func__, recvd_frame->bUnlockAEC, pme->m_bLedAfAecLock); 93 if(recvd_frame->bUnlockAEC && pme->m_bLedAfAecLock) { 94 qcamera_sm_internal_evt_payload_t *payload = 95 (qcamera_sm_internal_evt_payload_t *)malloc( 96 sizeof(qcamera_sm_internal_evt_payload_t)); 97 if (NULL != payload) { 98 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 99 payload->evt_type = QCAMERA_INTERNAL_EVT_RETRO_AEC_UNLOCK; 100 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 101 if (rc != NO_ERROR) { 102 ALOGE("%s: processEvt for retro AEC unlock failed", __func__); 103 free(payload); 104 payload = NULL; 105 } 106 } else { 107 ALOGE("%s: No memory for retro AEC event", __func__); 108 } 109 } 110 111 // Check if retro-active frames are completed and camera is 112 // ready to go ahead with LED estimation for regular frames 113 if (recvd_frame->bReadyForPrepareSnapshot) { 114 // Send an event 115 CDBG_HIGH("%s: [ZSL Retro] Ready for Prepare Snapshot, signal ", __func__); 116 qcamera_sm_internal_evt_payload_t *payload = 117 (qcamera_sm_internal_evt_payload_t *)malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 118 if (NULL != payload) { 119 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 120 payload->evt_type = QCAMERA_INTERNAL_EVT_READY_FOR_SNAPSHOT; 121 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 122 if (rc != NO_ERROR) { 123 ALOGE("%s: processEvt Ready for Snaphot failed", __func__); 124 free(payload); 125 payload = NULL; 126 } 127 } else { 128 ALOGE("%s: No memory for prepare signal event detect" 129 " qcamera_sm_internal_evt_payload_t", __func__); 130 } 131 } 132 133 /* indicate the parent that capture is done */ 134 pme->captureDone(); 135 136 // save a copy for the superbuf 137 mm_camera_super_buf_t* frame = 138 (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t)); 139 if (frame == NULL) { 140 ALOGE("%s: Error allocating memory to save received_frame structure.", __func__); 141 pChannel->bufDone(recvd_frame); 142 return; 143 } 144 *frame = *recvd_frame; 145 146 if (recvd_frame->num_bufs > 0) { 147 ALOGI("[KPI Perf] %s: superbuf frame_idx %d", __func__, 148 recvd_frame->bufs[0]->frame_idx); 149 } 150 151 // DUMP RAW if available 152 property_get("persist.camera.zsl_raw", value, "0"); 153 dump_raw = atoi(value) > 0 ? true : false; 154 if (dump_raw) { 155 for (uint32_t i = 0; i < recvd_frame->num_bufs; i++) { 156 if (recvd_frame->bufs[i]->stream_type == CAM_STREAM_TYPE_RAW) { 157 mm_camera_buf_def_t * raw_frame = recvd_frame->bufs[i]; 158 QCameraStream *pStream = pChannel->getStreamByHandle(raw_frame->stream_id); 159 if (NULL != pStream) { 160 pme->dumpFrameToFile(pStream, raw_frame, QCAMERA_DUMP_FRM_RAW); 161 } 162 break; 163 } 164 } 165 } 166 167 // DUMP YUV before reprocess if needed 168 property_get("persist.camera.zsl_yuv", value, "0"); 169 dump_yuv = atoi(value) > 0 ? true : false; 170 if (dump_yuv) { 171 for (uint32_t i = 0; i < recvd_frame->num_bufs; i++) { 172 if (recvd_frame->bufs[i]->stream_type == CAM_STREAM_TYPE_SNAPSHOT) { 173 mm_camera_buf_def_t * yuv_frame = recvd_frame->bufs[i]; 174 QCameraStream *pStream = pChannel->getStreamByHandle(yuv_frame->stream_id); 175 if (NULL != pStream) { 176 pme->dumpFrameToFile(pStream, yuv_frame, QCAMERA_DUMP_FRM_SNAPSHOT); 177 } 178 break; 179 } 180 } 181 } 182 // 183 // whether need FD Metadata along with Snapshot frame in ZSL mode 184 if(pme->needFDMetadata(QCAMERA_CH_TYPE_ZSL)){ 185 //Need Face Detection result for snapshot frames 186 //Get the Meta Data frames 187 mm_camera_buf_def_t *pMetaFrame = NULL; 188 for (uint32_t i = 0; i < frame->num_bufs; i++) { 189 QCameraStream *pStream = pChannel->getStreamByHandle(frame->bufs[i]->stream_id); 190 if (pStream != NULL) { 191 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) { 192 pMetaFrame = frame->bufs[i]; //find the metadata 193 break; 194 } 195 } 196 } 197 198 if(pMetaFrame != NULL){ 199 metadata_buffer_t *pMetaData = (metadata_buffer_t *)pMetaFrame->buffer; 200 //send the face detection info 201 uint8_t found = 0; 202 cam_face_detection_data_t faces_data; 203 IF_META_AVAILABLE(cam_face_detection_data_t, p_faces_data, 204 CAM_INTF_META_FACE_DETECTION, pMetaData) { 205 faces_data = *p_faces_data; 206 found = 1; 207 } else { 208 memset(&faces_data, 0, sizeof(cam_face_detection_data_t)); 209 } 210 faces_data.fd_type = QCAMERA_FD_SNAPSHOT; //HARD CODE here before MCT can support 211 if(!found){ 212 faces_data.num_faces_detected = 0; 213 }else if(faces_data.num_faces_detected > MAX_ROI){ 214 ALOGE("%s: Invalid number of faces %d", 215 __func__, faces_data.num_faces_detected); 216 } 217 qcamera_sm_internal_evt_payload_t *payload = 218 (qcamera_sm_internal_evt_payload_t *)malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 219 if (NULL != payload) { 220 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 221 payload->evt_type = QCAMERA_INTERNAL_EVT_FACE_DETECT_RESULT; 222 payload->faces_data = faces_data; 223 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 224 if (rc != NO_ERROR) { 225 ALOGE("%s: processEvt face_detection_result failed", __func__); 226 free(payload); 227 payload = NULL; 228 } 229 } else { 230 ALOGE("%s: No memory for face_detection_result qcamera_sm_internal_evt_payload_t", __func__); 231 } 232 } 233 } 234 235 property_get("persist.camera.dumpmetadata", value, "0"); 236 int32_t enabled = atoi(value); 237 if (enabled) { 238 mm_camera_buf_def_t *pMetaFrame = NULL; 239 QCameraStream *pStream = NULL; 240 for (uint32_t i = 0; i < frame->num_bufs; i++) { 241 pStream = pChannel->getStreamByHandle(frame->bufs[i]->stream_id); 242 if (pStream != NULL) { 243 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) { 244 pMetaFrame = frame->bufs[i]; 245 if (pMetaFrame != NULL && 246 ((metadata_buffer_t *)pMetaFrame->buffer)->is_tuning_params_valid) { 247 pme->dumpMetadataToFile(pStream, pMetaFrame, (char *) "ZSL_Snapshot"); 248 } 249 break; 250 } 251 } 252 } 253 } 254 255 property_get("persist.camera.zsl_matching", value, "0"); 256 log_matching = atoi(value) > 0 ? true : false; 257 if (log_matching) { 258 CDBG_HIGH("%s : ZSL super buffer contains:", __func__); 259 QCameraStream *pStream = NULL; 260 for (uint32_t i = 0; i < frame->num_bufs; i++) { 261 pStream = pChannel->getStreamByHandle(frame->bufs[i]->stream_id); 262 if (pStream != NULL ) { 263 CDBG_HIGH("%s: Buffer with V4L index %d frame index %d of type %d Timestamp: %ld %ld ", 264 __func__, 265 frame->bufs[i]->buf_idx, 266 frame->bufs[i]->frame_idx, 267 pStream->getMyType(), 268 frame->bufs[i]->ts.tv_sec, 269 frame->bufs[i]->ts.tv_nsec); 270 } 271 } 272 } 273 274 // Wait on Postproc initialization if needed 275 pme->waitDefferedWork(pme->mReprocJob); 276 277 // send to postprocessor 278 pme->m_postprocessor.processData(frame); 279 280 CDBG_HIGH("[KPI Perf] %s: X", __func__); 281 } 282 283 /*=========================================================================== 284 * FUNCTION : selectScene 285 * 286 * DESCRIPTION: send a preview callback when a specific selected scene is applied 287 * 288 * PARAMETERS : 289 * @pChannel: Camera channel 290 * @frame : Bundled super buffer 291 * 292 * RETURN : int32_t type of status 293 * NO_ERROR -- success 294 * none-zero failure code 295 *==========================================================================*/ 296 int32_t QCamera2HardwareInterface::selectScene(QCameraChannel *pChannel, 297 mm_camera_super_buf_t *frame) 298 { 299 mm_camera_buf_def_t *pMetaFrame = NULL; 300 QCameraStream *pStream = NULL; 301 int32_t rc = NO_ERROR; 302 303 if ((NULL == frame) || (NULL == pChannel)) { 304 ALOGE("%s: Invalid scene select input", __func__); 305 return BAD_VALUE; 306 } 307 308 cam_scene_mode_type selectedScene = mParameters.getSelectedScene(); 309 if (CAM_SCENE_MODE_MAX == selectedScene) { 310 ALOGV("%s: No selected scene", __func__); 311 return NO_ERROR; 312 } 313 314 for (uint32_t i = 0; i < frame->num_bufs; i++) { 315 pStream = pChannel->getStreamByHandle(frame->bufs[i]->stream_id); 316 if (pStream != NULL) { 317 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) { 318 pMetaFrame = frame->bufs[i]; 319 break; 320 } 321 } 322 } 323 324 if (NULL == pMetaFrame) { 325 ALOGE("%s: No metadata buffer found in scene select super buffer", __func__); 326 return NO_INIT; 327 } 328 329 metadata_buffer_t *pMetaData = (metadata_buffer_t *)pMetaFrame->buffer; 330 331 IF_META_AVAILABLE(cam_scene_mode_type, scene, CAM_INTF_META_CURRENT_SCENE, pMetaData) { 332 if ((*scene == selectedScene) && 333 (mDataCb != NULL) && 334 (msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_FRAME) > 0)) { 335 mm_camera_buf_def_t *preview_frame = NULL; 336 for (uint32_t i = 0; i < frame->num_bufs; i++) { 337 pStream = pChannel->getStreamByHandle(frame->bufs[i]->stream_id); 338 if (pStream != NULL) { 339 if (pStream->isTypeOf(CAM_STREAM_TYPE_PREVIEW)) { 340 preview_frame = frame->bufs[i]; 341 break; 342 } 343 } 344 } 345 if (preview_frame) { 346 QCameraGrallocMemory *memory = (QCameraGrallocMemory *)preview_frame->mem_info; 347 uint32_t idx = preview_frame->buf_idx; 348 rc = sendPreviewCallback(pStream, memory, idx); 349 if (NO_ERROR != rc) { 350 ALOGE("%s: Error triggering scene select preview callback", __func__); 351 } else { 352 mParameters.setSelectedScene(CAM_SCENE_MODE_MAX); 353 } 354 } else { 355 ALOGE("%s: No preview buffer found in scene select super buffer", __func__); 356 return NO_INIT; 357 } 358 } 359 } else { 360 ALOGE("%s: No current scene metadata!", __func__); 361 rc = NO_INIT; 362 } 363 364 return rc; 365 } 366 367 /*=========================================================================== 368 * FUNCTION : capture_channel_cb_routine 369 * 370 * DESCRIPTION: helper function to handle snapshot superbuf callback directly from 371 * mm-camera-interface 372 * 373 * PARAMETERS : 374 * @recvd_frame : received super buffer 375 * @userdata : user data ptr 376 * 377 * RETURN : None 378 * 379 * NOTE : recvd_frame will be released after this call by caller, so if 380 * async operation needed for recvd_frame, it's our responsibility 381 * to save a copy for this variable to be used later. 382 *==========================================================================*/ 383 void QCamera2HardwareInterface::capture_channel_cb_routine(mm_camera_super_buf_t *recvd_frame, 384 void *userdata) 385 { 386 ATRACE_CALL(); 387 char value[PROPERTY_VALUE_MAX]; 388 CDBG_HIGH("[KPI Perf] %s: E PROFILE_YUV_CB_TO_HAL", __func__); 389 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 390 if (pme == NULL || 391 pme->mCameraHandle == NULL || 392 pme->mCameraHandle->camera_handle != recvd_frame->camera_handle){ 393 ALOGE("%s: camera obj not valid", __func__); 394 return; 395 } 396 397 QCameraChannel *pChannel = pme->m_channels[QCAMERA_CH_TYPE_CAPTURE]; 398 if (pChannel == NULL || 399 pChannel->getMyHandle() != recvd_frame->ch_id) { 400 ALOGE("%s: Capture channel doesn't exist, return here", __func__); 401 return; 402 } 403 404 // save a copy for the superbuf 405 mm_camera_super_buf_t* frame = 406 (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t)); 407 if (frame == NULL) { 408 ALOGE("%s: Error allocating memory to save received_frame structure.", __func__); 409 pChannel->bufDone(recvd_frame); 410 return; 411 } 412 *frame = *recvd_frame; 413 414 property_get("persist.camera.dumpmetadata", value, "0"); 415 int32_t enabled = atoi(value); 416 if (enabled) { 417 mm_camera_buf_def_t *pMetaFrame = NULL; 418 QCameraStream *pStream = NULL; 419 for (uint32_t i = 0; i < frame->num_bufs; i++) { 420 pStream = pChannel->getStreamByHandle(frame->bufs[i]->stream_id); 421 if (pStream != NULL) { 422 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) { 423 pMetaFrame = frame->bufs[i]; //find the metadata 424 if (pMetaFrame != NULL && 425 ((metadata_buffer_t *)pMetaFrame->buffer)->is_tuning_params_valid) { 426 pme->dumpMetadataToFile(pStream, pMetaFrame, (char *) "Snapshot"); 427 } 428 break; 429 } 430 } 431 } 432 } 433 434 // Wait on Postproc initialization if needed 435 pme->waitDefferedWork(pme->mReprocJob); 436 437 // send to postprocessor 438 pme->m_postprocessor.processData(frame); 439 440 /* START of test register face image for face authentication */ 441 #ifdef QCOM_TEST_FACE_REGISTER_FACE 442 static uint8_t bRunFaceReg = 1; 443 444 if (bRunFaceReg > 0) { 445 // find snapshot frame 446 QCameraStream *main_stream = NULL; 447 mm_camera_buf_def_t *main_frame = NULL; 448 for (int i = 0; i < recvd_frame->num_bufs; i++) { 449 QCameraStream *pStream = 450 pChannel->getStreamByHandle(recvd_frame->bufs[i]->stream_id); 451 if (pStream != NULL) { 452 if (pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT)) { 453 main_stream = pStream; 454 main_frame = recvd_frame->bufs[i]; 455 break; 456 } 457 } 458 } 459 if (main_stream != NULL && main_frame != NULL) { 460 int32_t faceId = -1; 461 cam_pp_offline_src_config_t config; 462 memset(&config, 0, sizeof(cam_pp_offline_src_config_t)); 463 config.num_of_bufs = 1; 464 main_stream->getFormat(config.input_fmt); 465 main_stream->getFrameDimension(config.input_dim); 466 main_stream->getFrameOffset(config.input_buf_planes.plane_info); 467 CDBG_HIGH("DEBUG: registerFaceImage E"); 468 int32_t rc = pme->registerFaceImage(main_frame->buffer, &config, faceId); 469 CDBG_HIGH("DEBUG: registerFaceImage X, ret=%d, faceId=%d", rc, faceId); 470 bRunFaceReg = 0; 471 } 472 } 473 474 #endif 475 /* END of test register face image for face authentication */ 476 477 CDBG_HIGH("[KPI Perf] %s: X", __func__); 478 } 479 480 /*=========================================================================== 481 * FUNCTION : postproc_channel_cb_routine 482 * 483 * DESCRIPTION: helper function to handle postprocess superbuf callback directly from 484 * mm-camera-interface 485 * 486 * PARAMETERS : 487 * @recvd_frame : received super buffer 488 * @userdata : user data ptr 489 * 490 * RETURN : None 491 * 492 * NOTE : recvd_frame will be released after this call by caller, so if 493 * async operation needed for recvd_frame, it's our responsibility 494 * to save a copy for this variable to be used later. 495 *==========================================================================*/ 496 void QCamera2HardwareInterface::postproc_channel_cb_routine(mm_camera_super_buf_t *recvd_frame, 497 void *userdata) 498 { 499 ATRACE_CALL(); 500 CDBG_HIGH("[KPI Perf] %s: E", __func__); 501 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 502 if (pme == NULL || 503 pme->mCameraHandle == NULL || 504 pme->mCameraHandle->camera_handle != recvd_frame->camera_handle){ 505 ALOGE("%s: camera obj not valid", __func__); 506 return; 507 } 508 509 // save a copy for the superbuf 510 mm_camera_super_buf_t* frame = 511 (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t)); 512 if (frame == NULL) { 513 ALOGE("%s: Error allocating memory to save received_frame structure.", __func__); 514 return; 515 } 516 *frame = *recvd_frame; 517 518 // send to postprocessor 519 pme->m_postprocessor.processPPData(frame); 520 521 ATRACE_INT("Camera:Reprocess", 0); 522 CDBG_HIGH("[KPI Perf] %s: X", __func__); 523 } 524 525 /*=========================================================================== 526 * FUNCTION : preview_stream_cb_routine 527 * 528 * DESCRIPTION: helper function to handle preview frame from preview stream in 529 * normal case with display. 530 * 531 * PARAMETERS : 532 * @super_frame : received super buffer 533 * @stream : stream object 534 * @userdata : user data ptr 535 * 536 * RETURN : None 537 * 538 * NOTE : caller passes the ownership of super_frame, it's our 539 * responsibility to free super_frame once it's done. The new 540 * preview frame will be sent to display, and an older frame 541 * will be dequeued from display and needs to be returned back 542 * to kernel for future use. 543 *==========================================================================*/ 544 void QCamera2HardwareInterface::preview_stream_cb_routine(mm_camera_super_buf_t *super_frame, 545 QCameraStream * stream, 546 void *userdata) 547 { 548 ATRACE_CALL(); 549 CDBG_HIGH("[KPI Perf] %s : BEGIN", __func__); 550 int err = NO_ERROR; 551 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 552 QCameraGrallocMemory *memory = (QCameraGrallocMemory *)super_frame->bufs[0]->mem_info; 553 554 if (pme == NULL) { 555 ALOGE("%s: Invalid hardware object", __func__); 556 free(super_frame); 557 return; 558 } 559 if (memory == NULL) { 560 ALOGE("%s: Invalid memory object", __func__); 561 free(super_frame); 562 return; 563 } 564 565 mm_camera_buf_def_t *frame = super_frame->bufs[0]; 566 if (NULL == frame) { 567 ALOGE("%s: preview frame is NLUL", __func__); 568 free(super_frame); 569 return; 570 } 571 572 if (!pme->needProcessPreviewFrame()) { 573 ALOGE("%s: preview is not running, no need to process", __func__); 574 stream->bufDone(frame->buf_idx); 575 free(super_frame); 576 return; 577 } 578 579 if (pme->needDebugFps()) { 580 pme->debugShowPreviewFPS(); 581 } 582 583 uint32_t idx = frame->buf_idx; 584 pme->dumpFrameToFile(stream, frame, QCAMERA_DUMP_FRM_PREVIEW); 585 586 if(pme->m_bPreviewStarted) { 587 ALOGI("[KPI Perf] %s : PROFILE_FIRST_PREVIEW_FRAME", __func__); 588 pme->m_bPreviewStarted = false ; 589 } 590 591 // Display the buffer. 592 CDBG("%p displayBuffer %d E", pme, idx); 593 int dequeuedIdx = memory->displayBuffer(idx); 594 if (dequeuedIdx < 0 || dequeuedIdx >= memory->getCnt()) { 595 CDBG_HIGH("%s: Invalid dequeued buffer index %d from display", 596 __func__, dequeuedIdx); 597 } else { 598 // Return dequeued buffer back to driver 599 err = stream->bufDone((uint32_t)dequeuedIdx); 600 if ( err < 0) { 601 ALOGE("stream bufDone failed %d", err); 602 } 603 } 604 605 // Handle preview data callback 606 if (pme->mDataCb != NULL && 607 (pme->msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_FRAME) > 0) && 608 (!pme->mParameters.isSceneSelectionEnabled())) { 609 int32_t rc = pme->sendPreviewCallback(stream, memory, idx); 610 if (NO_ERROR != rc) { 611 ALOGE("%s: Preview callback was not sent succesfully", __func__); 612 } 613 } 614 615 free(super_frame); 616 CDBG_HIGH("[KPI Perf] %s : END", __func__); 617 return; 618 } 619 620 /*=========================================================================== 621 * FUNCTION : sendPreviewCallback 622 * 623 * DESCRIPTION: helper function for triggering preview callbacks 624 * 625 * PARAMETERS : 626 * @stream : stream object 627 * @memory : Gralloc memory allocator 628 * @idx : buffer index 629 * 630 * RETURN : int32_t type of status 631 * NO_ERROR -- success 632 * none-zero failure code 633 *==========================================================================*/ 634 int32_t QCamera2HardwareInterface::sendPreviewCallback(QCameraStream *stream, 635 QCameraGrallocMemory *memory, uint32_t idx) 636 { 637 camera_memory_t *previewMem = NULL; 638 camera_memory_t *data = NULL; 639 camera_memory_t *dataToApp = NULL; 640 size_t previewBufSize = 0; 641 size_t previewBufSizeFromCallback = 0; 642 cam_dimension_t preview_dim; 643 cam_format_t previewFmt; 644 int32_t rc = NO_ERROR; 645 int32_t yStride = 0; 646 int32_t yScanline = 0; 647 int32_t uvStride = 0; 648 int32_t uvScanline = 0; 649 int32_t uStride = 0; 650 int32_t uScanline = 0; 651 int32_t vStride = 0; 652 int32_t vScanline = 0; 653 int32_t yStrideToApp = 0; 654 int32_t uvStrideToApp = 0; 655 int32_t yScanlineToApp = 0; 656 int32_t uvScanlineToApp = 0; 657 int32_t srcOffset = 0; 658 int32_t dstOffset = 0; 659 int32_t srcBaseOffset = 0; 660 int32_t dstBaseOffset = 0; 661 int i; 662 663 if ((NULL == stream) || (NULL == memory)) { 664 ALOGE("%s: Invalid preview callback input", __func__); 665 return BAD_VALUE; 666 } 667 668 cam_stream_info_t *streamInfo = 669 reinterpret_cast<cam_stream_info_t *>(stream->getStreamInfoBuf()->getPtr(0)); 670 if (NULL == streamInfo) { 671 ALOGE("%s: Invalid streamInfo", __func__); 672 return BAD_VALUE; 673 } 674 675 stream->getFrameDimension(preview_dim); 676 stream->getFormat(previewFmt); 677 678 /* The preview buffer size in the callback should be 679 * (width*height*bytes_per_pixel). As all preview formats we support, 680 * use 12 bits per pixel, buffer size = previewWidth * previewHeight * 3/2. 681 * We need to put a check if some other formats are supported in future. */ 682 if ((previewFmt == CAM_FORMAT_YUV_420_NV21) || 683 (previewFmt == CAM_FORMAT_YUV_420_NV12) || 684 (previewFmt == CAM_FORMAT_YUV_420_YV12)) { 685 if(previewFmt == CAM_FORMAT_YUV_420_YV12) { 686 yStride = streamInfo->buf_planes.plane_info.mp[0].stride; 687 yScanline = streamInfo->buf_planes.plane_info.mp[0].scanline; 688 uStride = streamInfo->buf_planes.plane_info.mp[1].stride; 689 uScanline = streamInfo->buf_planes.plane_info.mp[1].scanline; 690 vStride = streamInfo->buf_planes.plane_info.mp[2].stride; 691 vScanline = streamInfo->buf_planes.plane_info.mp[2].scanline; 692 693 previewBufSize = (size_t) 694 (yStride * yScanline + uStride * uScanline + vStride * vScanline); 695 previewBufSizeFromCallback = previewBufSize; 696 } else { 697 yStride = streamInfo->buf_planes.plane_info.mp[0].stride; 698 yScanline = streamInfo->buf_planes.plane_info.mp[0].scanline; 699 uvStride = streamInfo->buf_planes.plane_info.mp[1].stride; 700 uvScanline = streamInfo->buf_planes.plane_info.mp[1].scanline; 701 702 yStrideToApp = preview_dim.width; 703 yScanlineToApp = preview_dim.height; 704 uvStrideToApp = yStrideToApp; 705 uvScanlineToApp = yScanlineToApp / 2; 706 707 previewBufSize = (size_t) 708 ((yStrideToApp * yScanlineToApp) + (uvStrideToApp * uvScanlineToApp)); 709 710 previewBufSizeFromCallback = (size_t) 711 ((yStride * yScanline) + (uvStride * uvScanline)); 712 } 713 if(previewBufSize == previewBufSizeFromCallback) { 714 previewMem = mGetMemory(memory->getFd(idx), 715 previewBufSize, 1, mCallbackCookie); 716 if (!previewMem || !previewMem->data) { 717 ALOGE("%s: mGetMemory failed.\n", __func__); 718 return NO_MEMORY; 719 } else { 720 data = previewMem; 721 } 722 } else { 723 data = memory->getMemory(idx, false); 724 dataToApp = mGetMemory(-1, previewBufSize, 1, mCallbackCookie); 725 if (!dataToApp || !dataToApp->data) { 726 ALOGE("%s: mGetMemory failed.\n", __func__); 727 return NO_MEMORY; 728 } 729 730 for (i = 0; i < preview_dim.height; i++) { 731 srcOffset = i * yStride; 732 dstOffset = i * yStrideToApp; 733 734 memcpy((unsigned char *) dataToApp->data + dstOffset, 735 (unsigned char *) data->data + srcOffset, 736 (size_t)yStrideToApp); 737 } 738 739 srcBaseOffset = yStride * yScanline; 740 dstBaseOffset = yStrideToApp * yScanlineToApp; 741 742 for (i = 0; i < preview_dim.height/2; i++) { 743 srcOffset = i * uvStride + srcBaseOffset; 744 dstOffset = i * uvStrideToApp + dstBaseOffset; 745 746 memcpy((unsigned char *) dataToApp->data + dstOffset, 747 (unsigned char *) data->data + srcOffset, 748 (size_t)yStrideToApp); 749 } 750 } 751 } else { 752 data = memory->getMemory(idx, false); 753 ALOGE("%s: Invalid preview format, buffer size in preview callback may be wrong.", 754 __func__); 755 } 756 qcamera_callback_argm_t cbArg; 757 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 758 cbArg.cb_type = QCAMERA_DATA_CALLBACK; 759 cbArg.msg_type = CAMERA_MSG_PREVIEW_FRAME; 760 if (previewBufSize != 0 && previewBufSizeFromCallback != 0 && 761 previewBufSize == previewBufSizeFromCallback) { 762 cbArg.data = data; 763 } else { 764 cbArg.data = dataToApp; 765 } 766 if ( previewMem ) { 767 cbArg.user_data = previewMem; 768 cbArg.release_cb = releaseCameraMemory; 769 } else if (dataToApp) { 770 cbArg.user_data = dataToApp; 771 cbArg.release_cb = releaseCameraMemory; 772 } 773 cbArg.cookie = this; 774 rc = m_cbNotifier.notifyCallback(cbArg); 775 if (rc != NO_ERROR) { 776 ALOGE("%s: fail sending notification", __func__); 777 if (previewMem) { 778 previewMem->release(previewMem); 779 } else if (dataToApp) { 780 dataToApp->release(dataToApp); 781 } 782 } 783 784 return rc; 785 } 786 787 /*=========================================================================== 788 * FUNCTION : nodisplay_preview_stream_cb_routine 789 * 790 * DESCRIPTION: helper function to handle preview frame from preview stream in 791 * no-display case 792 * 793 * PARAMETERS : 794 * @super_frame : received super buffer 795 * @stream : stream object 796 * @userdata : user data ptr 797 * 798 * RETURN : None 799 * 800 * NOTE : caller passes the ownership of super_frame, it's our 801 * responsibility to free super_frame once it's done. 802 *==========================================================================*/ 803 void QCamera2HardwareInterface::nodisplay_preview_stream_cb_routine( 804 mm_camera_super_buf_t *super_frame, 805 QCameraStream *stream, 806 void * userdata) 807 { 808 ATRACE_CALL(); 809 CDBG_HIGH("[KPI Perf] %s E",__func__); 810 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 811 if (pme == NULL || 812 pme->mCameraHandle == NULL || 813 pme->mCameraHandle->camera_handle != super_frame->camera_handle){ 814 ALOGE("%s: camera obj not valid", __func__); 815 // simply free super frame 816 free(super_frame); 817 return; 818 } 819 mm_camera_buf_def_t *frame = super_frame->bufs[0]; 820 if (NULL == frame) { 821 ALOGE("%s: preview frame is NULL", __func__); 822 free(super_frame); 823 return; 824 } 825 826 if (!pme->needProcessPreviewFrame()) { 827 CDBG_HIGH("%s: preview is not running, no need to process", __func__); 828 stream->bufDone(frame->buf_idx); 829 free(super_frame); 830 return; 831 } 832 833 if (pme->needDebugFps()) { 834 pme->debugShowPreviewFPS(); 835 } 836 837 QCameraMemory *previewMemObj = (QCameraMemory *)frame->mem_info; 838 camera_memory_t *preview_mem = NULL; 839 if (previewMemObj != NULL) { 840 preview_mem = previewMemObj->getMemory(frame->buf_idx, false); 841 } 842 if (NULL != previewMemObj && NULL != preview_mem) { 843 pme->dumpFrameToFile(stream, frame, QCAMERA_DUMP_FRM_PREVIEW); 844 845 if (pme->needProcessPreviewFrame() && 846 pme->mDataCb != NULL && 847 pme->msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_FRAME) > 0 ) { 848 qcamera_callback_argm_t cbArg; 849 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 850 cbArg.cb_type = QCAMERA_DATA_CALLBACK; 851 cbArg.msg_type = CAMERA_MSG_PREVIEW_FRAME; 852 cbArg.data = preview_mem; 853 cbArg.user_data = (void *) &frame->buf_idx; 854 cbArg.cookie = stream; 855 cbArg.release_cb = returnStreamBuffer; 856 int32_t rc = pme->m_cbNotifier.notifyCallback(cbArg); 857 if (rc != NO_ERROR) { 858 ALOGE("%s: fail sending data notify", __func__); 859 stream->bufDone(frame->buf_idx); 860 } 861 } else { 862 stream->bufDone(frame->buf_idx); 863 } 864 } 865 free(super_frame); 866 CDBG_HIGH("[KPI Perf] %s X",__func__); 867 } 868 869 /*=========================================================================== 870 * FUNCTION : rdi_mode_stream_cb_routine 871 * 872 * DESCRIPTION: helper function to handle RDI frame from preview stream in 873 * rdi mode case 874 * 875 * PARAMETERS : 876 * @super_frame : received super buffer 877 * @stream : stream object 878 * @userdata : user data ptr 879 * 880 * RETURN : None 881 * 882 * NOTE : caller passes the ownership of super_frame, it's our 883 * responsibility to free super_frame once it's done. 884 *==========================================================================*/ 885 void QCamera2HardwareInterface::rdi_mode_stream_cb_routine( 886 mm_camera_super_buf_t *super_frame, 887 QCameraStream *stream, 888 void * userdata) 889 { 890 ATRACE_CALL(); 891 CDBG_HIGH("RDI_DEBUG %s[%d]: Enter", __func__, __LINE__); 892 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 893 if (pme == NULL || 894 pme->mCameraHandle == NULL || 895 pme->mCameraHandle->camera_handle != super_frame->camera_handle){ 896 ALOGE("%s: camera obj not valid", __func__); 897 free(super_frame); 898 return; 899 } 900 mm_camera_buf_def_t *frame = super_frame->bufs[0]; 901 if (NULL == frame) { 902 ALOGE("%s: preview frame is NLUL", __func__); 903 goto end; 904 } 905 if (!pme->needProcessPreviewFrame()) { 906 ALOGE("%s: preview is not running, no need to process", __func__); 907 stream->bufDone(frame->buf_idx); 908 goto end; 909 } 910 if (pme->needDebugFps()) { 911 pme->debugShowPreviewFPS(); 912 } 913 // Non-secure Mode 914 if (!pme->isSecureMode()) { 915 QCameraMemory *previewMemObj = (QCameraMemory *)frame->mem_info; 916 if (NULL == previewMemObj) { 917 ALOGE("%s: previewMemObj is NULL", __func__); 918 stream->bufDone(frame->buf_idx); 919 goto end; 920 } 921 922 camera_memory_t *preview_mem = previewMemObj->getMemory(frame->buf_idx, false); 923 if (NULL != preview_mem) { 924 previewMemObj->cleanCache(frame->buf_idx); 925 // Dump RAW frame 926 pme->dumpFrameToFile(stream, frame, QCAMERA_DUMP_FRM_RAW); 927 // Notify Preview callback frame 928 if (pme->needProcessPreviewFrame() && 929 pme->mDataCb != NULL && 930 pme->msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_FRAME) > 0) { 931 qcamera_callback_argm_t cbArg; 932 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 933 cbArg.cb_type = QCAMERA_DATA_CALLBACK; 934 cbArg.msg_type = CAMERA_MSG_PREVIEW_FRAME; 935 cbArg.data = preview_mem; 936 cbArg.user_data = (void *) &frame->buf_idx; 937 cbArg.cookie = stream; 938 cbArg.release_cb = returnStreamBuffer; 939 pme->m_cbNotifier.notifyCallback(cbArg); 940 } else { 941 ALOGE("%s: preview_mem is NULL", __func__); 942 stream->bufDone(frame->buf_idx); 943 } 944 } 945 else { 946 ALOGE("%s: preview_mem is NULL", __func__); 947 stream->bufDone(frame->buf_idx); 948 } 949 } else { 950 // Secure Mode 951 // We will do QCAMERA_NOTIFY_CALLBACK and share FD in case of secure mode 952 QCameraMemory *previewMemObj = (QCameraMemory *)frame->mem_info; 953 if (NULL == previewMemObj) { 954 ALOGE("%s: previewMemObj is NULL", __func__); 955 stream->bufDone(frame->buf_idx); 956 goto end; 957 } 958 959 int fd = previewMemObj->getFd(frame->buf_idx); 960 ALOGD("%s: Preview frame fd =%d for index = %d ", __func__, fd, frame->buf_idx); 961 if (pme->needProcessPreviewFrame() && 962 pme->mDataCb != NULL && 963 pme->msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_FRAME) > 0) { 964 // Prepare Callback structure 965 qcamera_callback_argm_t cbArg; 966 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 967 cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK; 968 cbArg.msg_type = CAMERA_MSG_PREVIEW_FRAME; 969 #ifndef VANILLA_HAL 970 cbArg.ext1 = CAMERA_FRAME_DATA_FD; 971 cbArg.ext2 = fd; 972 #endif 973 cbArg.user_data = (void *) &frame->buf_idx; 974 cbArg.cookie = stream; 975 cbArg.release_cb = returnStreamBuffer; 976 pme->m_cbNotifier.notifyCallback(cbArg); 977 } else { 978 CDBG_HIGH("%s: No need to process preview frame, return buffer", __func__); 979 stream->bufDone(frame->buf_idx); 980 } 981 } 982 end: 983 free(super_frame); 984 CDBG_HIGH("RDI_DEBUG %s[%d]: Exit", __func__, __LINE__); 985 return; 986 } 987 988 /*=========================================================================== 989 * FUNCTION : postview_stream_cb_routine 990 * 991 * DESCRIPTION: helper function to handle post frame from postview stream 992 * 993 * PARAMETERS : 994 * @super_frame : received super buffer 995 * @stream : stream object 996 * @userdata : user data ptr 997 * 998 * RETURN : None 999 * 1000 * NOTE : caller passes the ownership of super_frame, it's our 1001 * responsibility to free super_frame once it's done. 1002 *==========================================================================*/ 1003 void QCamera2HardwareInterface::postview_stream_cb_routine(mm_camera_super_buf_t *super_frame, 1004 QCameraStream *stream, 1005 void *userdata) 1006 { 1007 ATRACE_CALL(); 1008 int err = NO_ERROR; 1009 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 1010 QCameraGrallocMemory *memory = (QCameraGrallocMemory *)super_frame->bufs[0]->mem_info; 1011 1012 if (pme == NULL) { 1013 ALOGE("%s: Invalid hardware object", __func__); 1014 free(super_frame); 1015 return; 1016 } 1017 if (memory == NULL) { 1018 ALOGE("%s: Invalid memory object", __func__); 1019 free(super_frame); 1020 return; 1021 } 1022 1023 CDBG_HIGH("[KPI Perf] %s : BEGIN", __func__); 1024 1025 mm_camera_buf_def_t *frame = super_frame->bufs[0]; 1026 if (NULL == frame) { 1027 ALOGE("%s: preview frame is NULL", __func__); 1028 free(super_frame); 1029 return; 1030 } 1031 1032 QCameraMemory *memObj = (QCameraMemory *)frame->mem_info; 1033 if (NULL != memObj) { 1034 pme->dumpFrameToFile(stream, frame, QCAMERA_DUMP_FRM_THUMBNAIL); 1035 } 1036 1037 // Return buffer back to driver 1038 err = stream->bufDone(frame->buf_idx); 1039 if ( err < 0) { 1040 ALOGE("stream bufDone failed %d", err); 1041 } 1042 1043 free(super_frame); 1044 CDBG_HIGH("[KPI Perf] %s : END", __func__); 1045 return; 1046 } 1047 1048 /*=========================================================================== 1049 * FUNCTION : video_stream_cb_routine 1050 * 1051 * DESCRIPTION: helper function to handle video frame from video stream 1052 * 1053 * PARAMETERS : 1054 * @super_frame : received super buffer 1055 * @stream : stream object 1056 * @userdata : user data ptr 1057 * 1058 * RETURN : None 1059 * 1060 * NOTE : caller passes the ownership of super_frame, it's our 1061 * responsibility to free super_frame once it's done. video 1062 * frame will be sent to video encoder. Once video encoder is 1063 * done with the video frame, it will call another API 1064 * (release_recording_frame) to return the frame back 1065 *==========================================================================*/ 1066 void QCamera2HardwareInterface::video_stream_cb_routine(mm_camera_super_buf_t *super_frame, 1067 QCameraStream *stream, 1068 void *userdata) 1069 { 1070 ATRACE_CALL(); 1071 CDBG_HIGH("[KPI Perf] %s : BEGIN", __func__); 1072 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 1073 if (pme == NULL || 1074 pme->mCameraHandle == NULL || 1075 pme->mCameraHandle->camera_handle != super_frame->camera_handle){ 1076 ALOGE("%s: camera obj not valid", __func__); 1077 // simply free super frame 1078 free(super_frame); 1079 return; 1080 } 1081 1082 mm_camera_buf_def_t *frame = super_frame->bufs[0]; 1083 1084 if (pme->needDebugFps()) { 1085 pme->debugShowVideoFPS(); 1086 } 1087 if(pme->m_bRecordStarted) { 1088 ALOGI("[KPI Perf] %s : PROFILE_FIRST_RECORD_FRAME", __func__); 1089 pme->m_bRecordStarted = false ; 1090 } 1091 CDBG_HIGH("%s: Stream(%d), Timestamp: %ld %ld", 1092 __func__, 1093 frame->stream_id, 1094 frame->ts.tv_sec, 1095 frame->ts.tv_nsec); 1096 1097 if (frame->buf_type == CAM_STREAM_BUF_TYPE_MPLANE) { 1098 nsecs_t timeStamp; 1099 timeStamp = nsecs_t(frame->ts.tv_sec) * 1000000000LL + frame->ts.tv_nsec; 1100 CDBG_HIGH("Send Video frame to services/encoder TimeStamp : %lld", 1101 timeStamp); 1102 QCameraMemory *videoMemObj = (QCameraMemory *)frame->mem_info; 1103 camera_memory_t *video_mem = NULL; 1104 if (NULL != videoMemObj) { 1105 video_mem = videoMemObj->getMemory(frame->buf_idx, 1106 (pme->mStoreMetaDataInFrame > 0)? true : false); 1107 } 1108 if (NULL != videoMemObj && NULL != video_mem) { 1109 pme->dumpFrameToFile(stream, frame, QCAMERA_DUMP_FRM_VIDEO); 1110 if ((pme->mDataCbTimestamp != NULL) && 1111 pme->msgTypeEnabledWithLock(CAMERA_MSG_VIDEO_FRAME) > 0) { 1112 qcamera_callback_argm_t cbArg; 1113 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 1114 cbArg.cb_type = QCAMERA_DATA_TIMESTAMP_CALLBACK; 1115 cbArg.msg_type = CAMERA_MSG_VIDEO_FRAME; 1116 cbArg.data = video_mem; 1117 cbArg.timestamp = timeStamp; 1118 int32_t rc = pme->m_cbNotifier.notifyCallback(cbArg); 1119 if (rc != NO_ERROR) { 1120 ALOGE("%s: fail sending data notify", __func__); 1121 stream->bufDone(frame->buf_idx); 1122 } 1123 } 1124 } 1125 } else { 1126 QCameraMemory *videoMemObj = (QCameraMemory *)frame->mem_info; 1127 camera_memory_t *video_mem = NULL; 1128 native_handle_t *nh = NULL; 1129 int fd_cnt = frame->user_buf.bufs_used; 1130 if (NULL != videoMemObj) { 1131 video_mem = videoMemObj->getMemory(frame->buf_idx, true); 1132 if (video_mem != NULL) { 1133 struct encoder_media_buffer_type * packet = 1134 (struct encoder_media_buffer_type *)video_mem->data; 1135 // fd cnt => Number of buffer FD's and buffer for offset, size, timestamp 1136 packet->meta_handle = native_handle_create(fd_cnt, (3 * fd_cnt)); 1137 packet->buffer_type = kMetadataBufferTypeCameraSource; 1138 nh = const_cast<native_handle_t *>(packet->meta_handle); 1139 } else { 1140 ALOGE("%s video_mem NULL", __func__); 1141 } 1142 } else { 1143 ALOGE("%s videoMemObj NULL", __func__); 1144 } 1145 1146 if (nh != NULL) { 1147 nsecs_t timeStamp; 1148 timeStamp = nsecs_t(frame->ts.tv_sec) * 1000000000LL 1149 + frame->ts.tv_nsec; 1150 CDBG("Batch buffer TimeStamp : %lld FD = %d index = %d fd_cnt = %d", 1151 timeStamp, frame->fd, frame->buf_idx, fd_cnt); 1152 1153 for (int i = 0; i < fd_cnt; i++) { 1154 if (frame->user_buf.buf_idx[i] >= 0) { 1155 mm_camera_buf_def_t *plane_frame = 1156 &frame->user_buf.plane_buf[frame->user_buf.buf_idx[i]]; 1157 QCameraMemory *frameobj = (QCameraMemory *)plane_frame->mem_info; 1158 nsecs_t frame_ts = nsecs_t(plane_frame->ts.tv_sec) * 1000000000LL 1159 + plane_frame->ts.tv_nsec; 1160 /*data[0] => FD data[1] => OFFSET data[2] => SIZE data[3] => TIMESTAMP*/ 1161 nh->data[i] = frameobj->getFd(plane_frame->buf_idx); 1162 nh->data[fd_cnt + i] = 0; 1163 nh->data[(2 * fd_cnt) + i] = (int)frameobj->getSize(plane_frame->buf_idx); 1164 nh->data[(3 * fd_cnt) + i] = (int)(frame_ts - timeStamp); 1165 CDBG("Send Video frames to services/encoder delta : %lld FD = %d index = %d", 1166 (frame_ts - timeStamp), plane_frame->fd, plane_frame->buf_idx); 1167 pme->dumpFrameToFile(stream, plane_frame, QCAMERA_DUMP_FRM_VIDEO); 1168 } 1169 } 1170 1171 if ((pme->mDataCbTimestamp != NULL) && 1172 pme->msgTypeEnabledWithLock(CAMERA_MSG_VIDEO_FRAME) > 0) { 1173 qcamera_callback_argm_t cbArg; 1174 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 1175 cbArg.cb_type = QCAMERA_DATA_TIMESTAMP_CALLBACK; 1176 cbArg.msg_type = CAMERA_MSG_VIDEO_FRAME; 1177 cbArg.data = video_mem; 1178 cbArg.timestamp = timeStamp; 1179 int32_t rc = pme->m_cbNotifier.notifyCallback(cbArg); 1180 if (rc != NO_ERROR) { 1181 ALOGE("%s: fail sending data notify", __func__); 1182 stream->bufDone(frame->buf_idx); 1183 } 1184 } 1185 } else { 1186 ALOGE("%s: No Video Meta Available. Return Buffer", __func__); 1187 stream->bufDone(super_frame->bufs[0]->buf_idx); 1188 } 1189 } 1190 free(super_frame); 1191 CDBG_HIGH("[KPI Perf] %s : END", __func__); 1192 } 1193 1194 /*=========================================================================== 1195 * FUNCTION : snapshot_channel_cb_routine 1196 * 1197 * DESCRIPTION: helper function to handle snapshot frame from snapshot channel 1198 * 1199 * PARAMETERS : 1200 * @super_frame : received super buffer 1201 * @userdata : user data ptr 1202 * 1203 * RETURN : None 1204 * 1205 * NOTE : recvd_frame will be released after this call by caller, so if 1206 * async operation needed for recvd_frame, it's our responsibility 1207 * to save a copy for this variable to be used later. 1208 *==========================================================================*/ 1209 void QCamera2HardwareInterface::snapshot_channel_cb_routine(mm_camera_super_buf_t *super_frame, 1210 void *userdata) 1211 { 1212 ATRACE_CALL(); 1213 char value[PROPERTY_VALUE_MAX]; 1214 1215 CDBG_HIGH("[KPI Perf] %s: E", __func__); 1216 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 1217 if (pme == NULL || 1218 pme->mCameraHandle == NULL || 1219 pme->mCameraHandle->camera_handle != super_frame->camera_handle){ 1220 ALOGE("%s: camera obj not valid", __func__); 1221 // simply free super frame 1222 free(super_frame); 1223 return; 1224 } 1225 1226 QCameraChannel *pChannel = pme->m_channels[QCAMERA_CH_TYPE_SNAPSHOT]; 1227 if ((pChannel == NULL) || (pChannel->getMyHandle() != super_frame->ch_id)) { 1228 ALOGE("%s: Snapshot channel doesn't exist, return here", __func__); 1229 return; 1230 } 1231 1232 property_get("persist.camera.dumpmetadata", value, "0"); 1233 int32_t enabled = atoi(value); 1234 if (enabled) { 1235 if (pChannel == NULL || 1236 pChannel->getMyHandle() != super_frame->ch_id) { 1237 ALOGE("%s: Capture channel doesn't exist, return here", __func__); 1238 return; 1239 } 1240 mm_camera_buf_def_t *pMetaFrame = NULL; 1241 QCameraStream *pStream = NULL; 1242 for (uint32_t i = 0; i < super_frame->num_bufs; i++) { 1243 pStream = pChannel->getStreamByHandle(super_frame->bufs[i]->stream_id); 1244 if (pStream != NULL) { 1245 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) { 1246 pMetaFrame = super_frame->bufs[i]; //find the metadata 1247 if (pMetaFrame != NULL && 1248 ((metadata_buffer_t *)pMetaFrame->buffer)->is_tuning_params_valid) { 1249 pme->dumpMetadataToFile(pStream, pMetaFrame, (char *) "Snapshot"); 1250 } 1251 break; 1252 } 1253 } 1254 } 1255 } 1256 1257 // save a copy for the superbuf 1258 mm_camera_super_buf_t* frame = (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t)); 1259 if (frame == NULL) { 1260 ALOGE("%s: Error allocating memory to save received_frame structure.", 1261 __func__); 1262 pChannel->bufDone(super_frame); 1263 return; 1264 } 1265 *frame = *super_frame; 1266 1267 pme->m_postprocessor.processData(frame); 1268 1269 CDBG_HIGH("[KPI Perf] %s: X", __func__); 1270 } 1271 1272 /*=========================================================================== 1273 * FUNCTION : raw_stream_cb_routine 1274 * 1275 * DESCRIPTION: helper function to handle raw dump frame from raw stream 1276 * 1277 * PARAMETERS : 1278 * @super_frame : received super buffer 1279 * @stream : stream object 1280 * @userdata : user data ptr 1281 * 1282 * RETURN : None 1283 * 1284 * NOTE : caller passes the ownership of super_frame, it's our 1285 * responsibility to free super_frame once it's done. For raw 1286 * frame, there is no need to send to postprocessor for jpeg 1287 * encoding. this function will play shutter and send the data 1288 * callback to upper layer. Raw frame buffer will be returned 1289 * back to kernel, and frame will be free after use. 1290 *==========================================================================*/ 1291 void QCamera2HardwareInterface::raw_stream_cb_routine(mm_camera_super_buf_t * super_frame, 1292 QCameraStream * /*stream*/, 1293 void * userdata) 1294 { 1295 ATRACE_CALL(); 1296 CDBG_HIGH("[KPI Perf] %s : BEGIN", __func__); 1297 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 1298 if (pme == NULL || 1299 pme->mCameraHandle == NULL || 1300 pme->mCameraHandle->camera_handle != super_frame->camera_handle){ 1301 ALOGE("%s: camera obj not valid", __func__); 1302 // simply free super frame 1303 free(super_frame); 1304 return; 1305 } 1306 1307 pme->m_postprocessor.processRawData(super_frame); 1308 CDBG_HIGH("[KPI Perf] %s : END", __func__); 1309 } 1310 1311 /*=========================================================================== 1312 * FUNCTION : preview_raw_stream_cb_routine 1313 * 1314 * DESCRIPTION: helper function to handle raw frame during standard preview 1315 * 1316 * PARAMETERS : 1317 * @super_frame : received super buffer 1318 * @stream : stream object 1319 * @userdata : user data ptr 1320 * 1321 * RETURN : None 1322 * 1323 * NOTE : caller passes the ownership of super_frame, it's our 1324 * responsibility to free super_frame once it's done. 1325 *==========================================================================*/ 1326 void QCamera2HardwareInterface::preview_raw_stream_cb_routine(mm_camera_super_buf_t * super_frame, 1327 QCameraStream * stream, 1328 void * userdata) 1329 { 1330 ATRACE_CALL(); 1331 CDBG_HIGH("[KPI Perf] %s : BEGIN", __func__); 1332 char value[PROPERTY_VALUE_MAX]; 1333 bool dump_raw = false; 1334 1335 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 1336 if (pme == NULL || 1337 pme->mCameraHandle == NULL || 1338 pme->mCameraHandle->camera_handle != super_frame->camera_handle){ 1339 ALOGE("%s: camera obj not valid", __func__); 1340 // simply free super frame 1341 free(super_frame); 1342 return; 1343 } 1344 1345 property_get("persist.camera.preview_raw", value, "0"); 1346 dump_raw = atoi(value) > 0 ? true : false; 1347 1348 for (uint32_t i = 0; i < super_frame->num_bufs; i++) { 1349 if (super_frame->bufs[i]->stream_type == CAM_STREAM_TYPE_RAW) { 1350 mm_camera_buf_def_t * raw_frame = super_frame->bufs[i]; 1351 if (NULL != stream) { 1352 if (dump_raw) { 1353 pme->dumpFrameToFile(stream, raw_frame, QCAMERA_DUMP_FRM_RAW); 1354 } 1355 stream->bufDone(super_frame->bufs[i]->buf_idx); 1356 } 1357 break; 1358 } 1359 } 1360 1361 free(super_frame); 1362 1363 CDBG_HIGH("[KPI Perf] %s : END", __func__); 1364 } 1365 1366 /*=========================================================================== 1367 * FUNCTION : snapshot_raw_stream_cb_routine 1368 * 1369 * DESCRIPTION: helper function to handle raw frame during standard capture 1370 * 1371 * PARAMETERS : 1372 * @super_frame : received super buffer 1373 * @stream : stream object 1374 * @userdata : user data ptr 1375 * 1376 * RETURN : None 1377 * 1378 * NOTE : caller passes the ownership of super_frame, it's our 1379 * responsibility to free super_frame once it's done. 1380 *==========================================================================*/ 1381 void QCamera2HardwareInterface::snapshot_raw_stream_cb_routine(mm_camera_super_buf_t * super_frame, 1382 QCameraStream * stream, 1383 void * userdata) 1384 { 1385 ATRACE_CALL(); 1386 CDBG_HIGH("[KPI Perf] %s : BEGIN", __func__); 1387 char value[PROPERTY_VALUE_MAX]; 1388 bool dump_raw = false; 1389 1390 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 1391 if (pme == NULL || 1392 pme->mCameraHandle == NULL || 1393 pme->mCameraHandle->camera_handle != super_frame->camera_handle){ 1394 ALOGE("%s: camera obj not valid", __func__); 1395 // simply free super frame 1396 free(super_frame); 1397 return; 1398 } 1399 1400 property_get("persist.camera.snapshot_raw", value, "0"); 1401 dump_raw = atoi(value) > 0 ? true : false; 1402 1403 for (uint32_t i = 0; i < super_frame->num_bufs; i++) { 1404 if (super_frame->bufs[i]->stream_type == CAM_STREAM_TYPE_RAW) { 1405 mm_camera_buf_def_t * raw_frame = super_frame->bufs[i]; 1406 if (NULL != stream) { 1407 if (dump_raw) { 1408 pme->dumpFrameToFile(stream, raw_frame, QCAMERA_DUMP_FRM_RAW); 1409 } 1410 stream->bufDone(super_frame->bufs[i]->buf_idx); 1411 } 1412 break; 1413 } 1414 } 1415 1416 free(super_frame); 1417 1418 CDBG_HIGH("[KPI Perf] %s : END", __func__); 1419 } 1420 1421 /*=========================================================================== 1422 * FUNCTION : updateMetadata 1423 * 1424 * DESCRIPTION: Frame related parameter can be updated here 1425 * 1426 * PARAMETERS : 1427 * @pMetaData : pointer to metadata buffer 1428 * 1429 * RETURN : int32_t type of status 1430 * NO_ERROR -- success 1431 * none-zero failure code 1432 *==========================================================================*/ 1433 int32_t QCamera2HardwareInterface::updateMetadata(metadata_buffer_t *pMetaData) 1434 { 1435 int32_t rc = NO_ERROR; 1436 1437 if (pMetaData == NULL) { 1438 ALOGE("%s: Null Metadata buffer", __func__); 1439 return rc; 1440 } 1441 1442 // Sharpness 1443 cam_edge_application_t edge_application; 1444 memset(&edge_application, 0x00, sizeof(cam_edge_application_t)); 1445 edge_application.sharpness = mParameters.getSharpness(); 1446 if (edge_application.sharpness != 0) { 1447 edge_application.edge_mode = CAM_EDGE_MODE_FAST; 1448 } else { 1449 edge_application.edge_mode = CAM_EDGE_MODE_OFF; 1450 } 1451 ADD_SET_PARAM_ENTRY_TO_BATCH(pMetaData, 1452 CAM_INTF_META_EDGE_MODE, edge_application); 1453 1454 //Effect 1455 int32_t prmEffect = mParameters.getEffect(); 1456 ADD_SET_PARAM_ENTRY_TO_BATCH(pMetaData, CAM_INTF_PARM_EFFECT, prmEffect); 1457 1458 //flip 1459 int32_t prmFlip = mParameters.getFlipMode(CAM_STREAM_TYPE_SNAPSHOT); 1460 ADD_SET_PARAM_ENTRY_TO_BATCH(pMetaData, CAM_INTF_PARM_FLIP, prmFlip); 1461 1462 //denoise 1463 uint8_t prmDenoise = (uint8_t)mParameters.isWNREnabled(); 1464 ADD_SET_PARAM_ENTRY_TO_BATCH(pMetaData, 1465 CAM_INTF_META_NOISE_REDUCTION_MODE, prmDenoise); 1466 1467 //rotation & device rotation 1468 uint32_t prmRotation = mParameters.getJpegRotation(); 1469 cam_rotation_info_t rotation_info; 1470 if (prmRotation == 0) { 1471 rotation_info.rotation = ROTATE_0; 1472 } else if (prmRotation == 90) { 1473 rotation_info.rotation = ROTATE_90; 1474 } else if (prmRotation == 180) { 1475 rotation_info.rotation = ROTATE_180; 1476 } else if (prmRotation == 270) { 1477 rotation_info.rotation = ROTATE_270; 1478 } 1479 1480 uint32_t device_rotation = mParameters.getDeviceRotation(); 1481 if (device_rotation == 0) { 1482 rotation_info.device_rotation = ROTATE_0; 1483 } else if (device_rotation == 90) { 1484 rotation_info.device_rotation = ROTATE_90; 1485 } else if (device_rotation == 180) { 1486 rotation_info.device_rotation = ROTATE_180; 1487 } else if (device_rotation == 270) { 1488 rotation_info.device_rotation = ROTATE_270; 1489 } else { 1490 rotation_info.device_rotation = ROTATE_0; 1491 } 1492 ADD_SET_PARAM_ENTRY_TO_BATCH(pMetaData, CAM_INTF_PARM_ROTATION, rotation_info); 1493 1494 return rc; 1495 } 1496 1497 /*=========================================================================== 1498 * FUNCTION : metadata_stream_cb_routine 1499 * 1500 * DESCRIPTION: helper function to handle metadata frame from metadata stream 1501 * 1502 * PARAMETERS : 1503 * @super_frame : received super buffer 1504 * @stream : stream object 1505 * @userdata : user data ptr 1506 * 1507 * RETURN : None 1508 * 1509 * NOTE : caller passes the ownership of super_frame, it's our 1510 * responsibility to free super_frame once it's done. Metadata 1511 * could have valid entries for face detection result or 1512 * histogram statistics information. 1513 *==========================================================================*/ 1514 void QCamera2HardwareInterface::metadata_stream_cb_routine(mm_camera_super_buf_t * super_frame, 1515 QCameraStream * stream, 1516 void * userdata) 1517 { 1518 ATRACE_CALL(); 1519 CDBG("[KPI Perf] %s : BEGIN", __func__); 1520 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 1521 if (pme == NULL || 1522 pme->mCameraHandle == NULL || 1523 pme->mCameraHandle->camera_handle != super_frame->camera_handle){ 1524 ALOGE("%s: camera obj not valid", __func__); 1525 // simply free super frame 1526 free(super_frame); 1527 return; 1528 } 1529 1530 mm_camera_buf_def_t *frame = super_frame->bufs[0]; 1531 metadata_buffer_t *pMetaData = (metadata_buffer_t *)frame->buffer; 1532 if(pme->m_stateMachine.isNonZSLCaptureRunning()&& 1533 !pme->mLongshotEnabled) { 1534 //Make shutter call back in non ZSL mode once raw frame is received from VFE. 1535 pme->playShutter(); 1536 } 1537 1538 if (pMetaData->is_tuning_params_valid && pme->mParameters.getRecordingHintValue() == true) { 1539 //Dump Tuning data for video 1540 pme->dumpMetadataToFile(stream,frame,(char *)"Video"); 1541 } 1542 1543 IF_META_AVAILABLE(cam_hist_stats_t, stats_data, CAM_INTF_META_HISTOGRAM, pMetaData) { 1544 // process histogram statistics info 1545 qcamera_sm_internal_evt_payload_t *payload = 1546 (qcamera_sm_internal_evt_payload_t *) 1547 malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 1548 if (NULL != payload) { 1549 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 1550 payload->evt_type = QCAMERA_INTERNAL_EVT_HISTOGRAM_STATS; 1551 payload->stats_data = *stats_data; 1552 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 1553 if (rc != NO_ERROR) { 1554 ALOGE("%s: processEvt histogram failed", __func__); 1555 free(payload); 1556 payload = NULL; 1557 1558 } 1559 } else { 1560 ALOGE("%s: No memory for histogram qcamera_sm_internal_evt_payload_t", __func__); 1561 } 1562 } 1563 1564 IF_META_AVAILABLE(cam_face_detection_data_t, faces_data, 1565 CAM_INTF_META_FACE_DETECTION, pMetaData) { 1566 if (faces_data->num_faces_detected > MAX_ROI) { 1567 ALOGE("%s: Invalid number of faces %d", 1568 __func__, faces_data->num_faces_detected); 1569 } else { 1570 // process face detection result 1571 if (faces_data->num_faces_detected) 1572 CDBG_HIGH("[KPI Perf] %s: PROFILE_NUMBER_OF_FACES_DETECTED %d", 1573 __func__,faces_data->num_faces_detected); 1574 faces_data->fd_type = QCAMERA_FD_PREVIEW; //HARD CODE here before MCT can support 1575 qcamera_sm_internal_evt_payload_t *payload = (qcamera_sm_internal_evt_payload_t *) 1576 malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 1577 if (NULL != payload) { 1578 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 1579 payload->evt_type = QCAMERA_INTERNAL_EVT_FACE_DETECT_RESULT; 1580 payload->faces_data = *faces_data; 1581 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 1582 if (rc != NO_ERROR) { 1583 ALOGE("%s: processEvt face detection failed", __func__); 1584 free(payload); 1585 payload = NULL; 1586 } 1587 } else { 1588 ALOGE("%s: No memory for face detect qcamera_sm_internal_evt_payload_t", __func__); 1589 } 1590 } 1591 } 1592 1593 IF_META_AVAILABLE(cam_auto_focus_data_t, focus_data, 1594 CAM_INTF_META_AUTOFOCUS_DATA, pMetaData) { 1595 qcamera_sm_internal_evt_payload_t *payload = 1596 (qcamera_sm_internal_evt_payload_t *)malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 1597 if (NULL != payload) { 1598 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 1599 payload->evt_type = QCAMERA_INTERNAL_EVT_FOCUS_UPDATE; 1600 payload->focus_data = *focus_data; 1601 payload->focus_data.focused_frame_idx = frame->frame_idx; 1602 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 1603 if (rc != NO_ERROR) { 1604 ALOGE("%s: processEvt focus failed", __func__); 1605 free(payload); 1606 payload = NULL; 1607 1608 } 1609 } else { 1610 ALOGE("%s: No memory for focus qcamera_sm_internal_evt_payload_t", __func__); 1611 } 1612 } 1613 1614 IF_META_AVAILABLE(cam_crop_data_t, crop_data, CAM_INTF_META_CROP_DATA, pMetaData) { 1615 if (crop_data->num_of_streams > MAX_NUM_STREAMS) { 1616 ALOGE("%s: Invalid num_of_streams %d in crop_data", __func__, 1617 crop_data->num_of_streams); 1618 } else { 1619 qcamera_sm_internal_evt_payload_t *payload = 1620 (qcamera_sm_internal_evt_payload_t *) 1621 malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 1622 if (NULL != payload) { 1623 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 1624 payload->evt_type = QCAMERA_INTERNAL_EVT_CROP_INFO; 1625 payload->crop_data = *crop_data; 1626 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 1627 if (rc != NO_ERROR) { 1628 ALOGE("%s: processEvt crop info failed", __func__); 1629 free(payload); 1630 payload = NULL; 1631 1632 } 1633 } else { 1634 ALOGE("%s: No memory for prep_snapshot qcamera_sm_internal_evt_payload_t", 1635 __func__); 1636 } 1637 } 1638 } 1639 1640 IF_META_AVAILABLE(int32_t, prep_snapshot_done_state, 1641 CAM_INTF_META_PREP_SNAPSHOT_DONE, pMetaData) { 1642 qcamera_sm_internal_evt_payload_t *payload = 1643 (qcamera_sm_internal_evt_payload_t *)malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 1644 if (NULL != payload) { 1645 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 1646 payload->evt_type = QCAMERA_INTERNAL_EVT_PREP_SNAPSHOT_DONE; 1647 payload->prep_snapshot_state = (cam_prep_snapshot_state_t)*prep_snapshot_done_state; 1648 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 1649 if (rc != NO_ERROR) { 1650 ALOGE("%s: processEvt prep_snapshot failed", __func__); 1651 free(payload); 1652 payload = NULL; 1653 1654 } 1655 } else { 1656 ALOGE("%s: No memory for prep_snapshot qcamera_sm_internal_evt_payload_t", __func__); 1657 } 1658 } 1659 1660 IF_META_AVAILABLE(cam_asd_hdr_scene_data_t, hdr_scene_data, 1661 CAM_INTF_META_ASD_HDR_SCENE_DATA, pMetaData) { 1662 CDBG_HIGH("%s: hdr_scene_data: %d %f\n", __func__, 1663 hdr_scene_data->is_hdr_scene, hdr_scene_data->hdr_confidence); 1664 //Handle this HDR meta data only if capture is not in process 1665 if (!pme->m_stateMachine.isCaptureRunning()) { 1666 qcamera_sm_internal_evt_payload_t *payload = 1667 (qcamera_sm_internal_evt_payload_t *) 1668 malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 1669 if (NULL != payload) { 1670 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 1671 payload->evt_type = QCAMERA_INTERNAL_EVT_HDR_UPDATE; 1672 payload->hdr_data = *hdr_scene_data; 1673 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 1674 if (rc != NO_ERROR) { 1675 ALOGE("%s: processEvt hdr update failed", __func__); 1676 free(payload); 1677 payload = NULL; 1678 } 1679 } else { 1680 ALOGE("%s: No memory for hdr update qcamera_sm_internal_evt_payload_t", 1681 __func__); 1682 } 1683 } 1684 } 1685 1686 IF_META_AVAILABLE(int32_t, scene, CAM_INTF_META_ASD_SCENE_TYPE, pMetaData) { 1687 qcamera_sm_internal_evt_payload_t *payload = 1688 (qcamera_sm_internal_evt_payload_t *)malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 1689 if (NULL != payload) { 1690 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 1691 payload->evt_type = QCAMERA_INTERNAL_EVT_ASD_UPDATE; 1692 payload->asd_data = (cam_auto_scene_t)*scene; 1693 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 1694 if (rc != NO_ERROR) { 1695 ALOGE("%s: processEvt asd_update failed", __func__); 1696 free(payload); 1697 payload = NULL; 1698 } 1699 } else { 1700 ALOGE("%s: No memory for asd_update qcamera_sm_internal_evt_payload_t", __func__); 1701 } 1702 } 1703 1704 IF_META_AVAILABLE(cam_awb_params_t, awb_params, CAM_INTF_META_AWB_INFO, pMetaData) { 1705 CDBG_HIGH("%s, metadata for awb params.", __func__); 1706 qcamera_sm_internal_evt_payload_t *payload = 1707 (qcamera_sm_internal_evt_payload_t *) 1708 malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 1709 if (NULL != payload) { 1710 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 1711 payload->evt_type = QCAMERA_INTERNAL_EVT_AWB_UPDATE; 1712 payload->awb_data = *awb_params; 1713 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 1714 if (rc != NO_ERROR) { 1715 ALOGE("%s: processEvt awb_update failed", __func__); 1716 free(payload); 1717 payload = NULL; 1718 } 1719 } else { 1720 ALOGE("%s: No memory for awb_update qcamera_sm_internal_evt_payload_t", __func__); 1721 } 1722 } 1723 1724 IF_META_AVAILABLE(uint32_t, flash_mode, CAM_INTF_META_FLASH_MODE, pMetaData) { 1725 pme->mExifParams.sensor_params.flash_mode = (cam_flash_mode_t)*flash_mode; 1726 } 1727 1728 IF_META_AVAILABLE(int32_t, flash_state, CAM_INTF_META_FLASH_STATE, pMetaData) { 1729 pme->mExifParams.sensor_params.flash_state = (cam_flash_state_t) *flash_state; 1730 } 1731 1732 IF_META_AVAILABLE(float, aperture_value, CAM_INTF_META_LENS_APERTURE, pMetaData) { 1733 pme->mExifParams.sensor_params.aperture_value = *aperture_value; 1734 } 1735 1736 IF_META_AVAILABLE(cam_3a_params_t, ae_params, CAM_INTF_META_AEC_INFO, pMetaData) { 1737 pme->mExifParams.cam_3a_params = *ae_params; 1738 pme->mExifParams.cam_3a_params_valid = TRUE; 1739 pme->mFlashNeeded = ae_params->flash_needed; 1740 pme->mExifParams.cam_3a_params.brightness = (float) pme->mParameters.getBrightness(); 1741 qcamera_sm_internal_evt_payload_t *payload = 1742 (qcamera_sm_internal_evt_payload_t *) 1743 malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 1744 if (NULL != payload) { 1745 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 1746 payload->evt_type = QCAMERA_INTERNAL_EVT_AE_UPDATE; 1747 payload->ae_data = *ae_params; 1748 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 1749 if (rc != NO_ERROR) { 1750 ALOGE("%s: processEvt ae_update failed", __func__); 1751 free(payload); 1752 payload = NULL; 1753 } 1754 } else { 1755 ALOGE("%s: No memory for ae_update qcamera_sm_internal_evt_payload_t", __func__); 1756 } 1757 } 1758 1759 IF_META_AVAILABLE(int32_t, wb_mode, CAM_INTF_PARM_WHITE_BALANCE, pMetaData) { 1760 pme->mExifParams.cam_3a_params.wb_mode = (cam_wb_mode_type) *wb_mode; 1761 } 1762 1763 IF_META_AVAILABLE(cam_sensor_params_t, sensor_params, CAM_INTF_META_SENSOR_INFO, pMetaData) { 1764 pme->mExifParams.sensor_params = *sensor_params; 1765 } 1766 1767 IF_META_AVAILABLE(cam_ae_exif_debug_t, ae_exif_debug_params, 1768 CAM_INTF_META_EXIF_DEBUG_AE, pMetaData) { 1769 pme->mExifParams.ae_debug_params = *ae_exif_debug_params; 1770 pme->mExifParams.ae_debug_params_valid = TRUE; 1771 } 1772 1773 IF_META_AVAILABLE(cam_awb_exif_debug_t, awb_exif_debug_params, 1774 CAM_INTF_META_EXIF_DEBUG_AWB, pMetaData) { 1775 pme->mExifParams.awb_debug_params = *awb_exif_debug_params; 1776 pme->mExifParams.awb_debug_params_valid = TRUE; 1777 } 1778 1779 IF_META_AVAILABLE(cam_af_exif_debug_t, af_exif_debug_params, 1780 CAM_INTF_META_EXIF_DEBUG_AF, pMetaData) { 1781 pme->mExifParams.af_debug_params = *af_exif_debug_params; 1782 pme->mExifParams.af_debug_params_valid = TRUE; 1783 } 1784 1785 IF_META_AVAILABLE(cam_asd_exif_debug_t, asd_exif_debug_params, 1786 CAM_INTF_META_EXIF_DEBUG_ASD, pMetaData) { 1787 pme->mExifParams.asd_debug_params = *asd_exif_debug_params; 1788 pme->mExifParams.asd_debug_params_valid = TRUE; 1789 } 1790 1791 IF_META_AVAILABLE(cam_stats_buffer_exif_debug_t, stats_exif_debug_params, 1792 CAM_INTF_META_EXIF_DEBUG_STATS, pMetaData) { 1793 pme->mExifParams.stats_debug_params = *stats_exif_debug_params; 1794 pme->mExifParams.stats_debug_params_valid = TRUE; 1795 } 1796 1797 IF_META_AVAILABLE(uint32_t, led_mode, CAM_INTF_META_LED_MODE_OVERRIDE, pMetaData) { 1798 qcamera_sm_internal_evt_payload_t *payload = 1799 (qcamera_sm_internal_evt_payload_t *) 1800 malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 1801 if (NULL != payload) { 1802 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 1803 payload->evt_type = QCAMERA_INTERNAL_EVT_LED_MODE_OVERRIDE; 1804 payload->led_data = (cam_flash_mode_t)*led_mode; 1805 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 1806 if (rc != NO_ERROR) { 1807 ALOGE("%s: processEvt led mode override failed", __func__); 1808 free(payload); 1809 payload = NULL; 1810 } 1811 } else { 1812 ALOGE("%s: No memory for focus qcamera_sm_internal_evt_payload_t", __func__); 1813 } 1814 } 1815 1816 cam_edge_application_t edge_application; 1817 memset(&edge_application, 0x00, sizeof(cam_edge_application_t)); 1818 edge_application.sharpness = pme->mParameters.getSharpness(); 1819 if (edge_application.sharpness != 0) { 1820 edge_application.edge_mode = CAM_EDGE_MODE_FAST; 1821 } else { 1822 edge_application.edge_mode = CAM_EDGE_MODE_OFF; 1823 } 1824 ADD_SET_PARAM_ENTRY_TO_BATCH(pMetaData, CAM_INTF_META_EDGE_MODE, edge_application); 1825 1826 IF_META_AVAILABLE(cam_focus_pos_info_t, cur_pos_info, 1827 CAM_INTF_META_FOCUS_POSITION, pMetaData) { 1828 qcamera_sm_internal_evt_payload_t *payload = 1829 (qcamera_sm_internal_evt_payload_t *)malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 1830 if (NULL != payload) { 1831 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 1832 payload->evt_type = QCAMERA_INTERNAL_EVT_FOCUS_POS_UPDATE; 1833 payload->focus_pos = *cur_pos_info; 1834 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 1835 if (rc != NO_ERROR) { 1836 ALOGE("%s: processEvt focus_pos_update failed", __func__); 1837 free(payload); 1838 payload = NULL; 1839 } 1840 } else { 1841 ALOGE("%s: No memory for focus_pos_update qcamera_sm_internal_evt_payload_t", __func__); 1842 } 1843 } 1844 1845 stream->bufDone(frame->buf_idx); 1846 free(super_frame); 1847 1848 CDBG("[KPI Perf] %s : END", __func__); 1849 } 1850 1851 /*=========================================================================== 1852 * FUNCTION : reprocess_stream_cb_routine 1853 * 1854 * DESCRIPTION: helper function to handle reprocess frame from reprocess stream 1855 (after reprocess, e.g., ZSL snapshot frame after WNR if 1856 * WNR is enabled) 1857 * 1858 * PARAMETERS : 1859 * @super_frame : received super buffer 1860 * @stream : stream object 1861 * @userdata : user data ptr 1862 * 1863 * RETURN : None 1864 * 1865 * NOTE : caller passes the ownership of super_frame, it's our 1866 * responsibility to free super_frame once it's done. In this 1867 * case, reprocessed frame need to be passed to postprocessor 1868 * for jpeg encoding. 1869 *==========================================================================*/ 1870 void QCamera2HardwareInterface::reprocess_stream_cb_routine(mm_camera_super_buf_t * super_frame, 1871 QCameraStream * /*stream*/, 1872 void * userdata) 1873 { 1874 ATRACE_CALL(); 1875 CDBG_HIGH("[KPI Perf] %s: E", __func__); 1876 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 1877 if (pme == NULL || 1878 pme->mCameraHandle == NULL || 1879 pme->mCameraHandle->camera_handle != super_frame->camera_handle){ 1880 ALOGE("%s: camera obj not valid", __func__); 1881 // simply free super frame 1882 free(super_frame); 1883 return; 1884 } 1885 1886 pme->m_postprocessor.processPPData(super_frame); 1887 1888 CDBG_HIGH("[KPI Perf] %s: X", __func__); 1889 } 1890 1891 /*=========================================================================== 1892 * FUNCTION : dumpFrameToFile 1893 * 1894 * DESCRIPTION: helper function to dump jpeg into file for debug purpose. 1895 * 1896 * PARAMETERS : 1897 * @data : data ptr 1898 * @size : length of data buffer 1899 * @index : identifier for data 1900 * 1901 * RETURN : None 1902 *==========================================================================*/ 1903 void QCamera2HardwareInterface::dumpJpegToFile(const void *data, 1904 size_t size, uint32_t index) 1905 { 1906 char value[PROPERTY_VALUE_MAX]; 1907 property_get("persist.camera.dumpimg", value, "0"); 1908 uint32_t enabled = (uint32_t) atoi(value); 1909 uint32_t frm_num = 0; 1910 uint32_t skip_mode = 0; 1911 1912 char buf[32]; 1913 cam_dimension_t dim; 1914 memset(buf, 0, sizeof(buf)); 1915 memset(&dim, 0, sizeof(dim)); 1916 1917 if(((enabled & QCAMERA_DUMP_FRM_JPEG) && data) || 1918 ((true == m_bIntJpegEvtPending) && data)) { 1919 frm_num = ((enabled & 0xffff0000) >> 16); 1920 if(frm_num == 0) { 1921 frm_num = 10; //default 10 frames 1922 } 1923 if(frm_num > 256) { 1924 frm_num = 256; //256 buffers cycle around 1925 } 1926 skip_mode = ((enabled & 0x0000ff00) >> 8); 1927 if(skip_mode == 0) { 1928 skip_mode = 1; //no-skip 1929 } 1930 1931 if( mDumpSkipCnt % skip_mode == 0) { 1932 if((frm_num == 256) && (mDumpFrmCnt >= frm_num)) { 1933 // reset frame count if cycling 1934 mDumpFrmCnt = 0; 1935 } 1936 if (mDumpFrmCnt <= frm_num) { 1937 snprintf(buf, sizeof(buf), QCAMERA_DUMP_FRM_LOCATION "%d_%d.jpg", 1938 mDumpFrmCnt, index); 1939 if (true == m_bIntJpegEvtPending) { 1940 strlcpy(m_BackendFileName, buf, sizeof(buf)); 1941 mBackendFileSize = size; 1942 } 1943 1944 int file_fd = open(buf, O_RDWR | O_CREAT, 0777); 1945 if (file_fd >= 0) { 1946 ssize_t written_len = write(file_fd, data, size); 1947 fchmod(file_fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 1948 CDBG_HIGH("%s: written number of bytes %zd\n", 1949 __func__, written_len); 1950 close(file_fd); 1951 } else { 1952 ALOGE("%s: fail t open file for image dumping", __func__); 1953 } 1954 if (false == m_bIntJpegEvtPending) { 1955 mDumpFrmCnt++; 1956 } 1957 } 1958 } 1959 mDumpSkipCnt++; 1960 } 1961 } 1962 1963 1964 void QCamera2HardwareInterface::dumpMetadataToFile(QCameraStream *stream, 1965 mm_camera_buf_def_t *frame,char *type) 1966 { 1967 char value[PROPERTY_VALUE_MAX]; 1968 uint32_t frm_num = 0; 1969 metadata_buffer_t *metadata = (metadata_buffer_t *)frame->buffer; 1970 property_get("persist.camera.dumpmetadata", value, "0"); 1971 uint32_t enabled = (uint32_t) atoi(value); 1972 if (stream == NULL) { 1973 CDBG_HIGH("No op"); 1974 return; 1975 } 1976 1977 uint32_t dumpFrmCnt = stream->mDumpMetaFrame; 1978 if(enabled){ 1979 frm_num = ((enabled & 0xffff0000) >> 16); 1980 if (frm_num == 0) { 1981 frm_num = 10; //default 10 frames 1982 } 1983 if (frm_num > 256) { 1984 frm_num = 256; //256 buffers cycle around 1985 } 1986 if ((frm_num == 256) && (dumpFrmCnt >= frm_num)) { 1987 // reset frame count if cycling 1988 dumpFrmCnt = 0; 1989 } 1990 CDBG_HIGH("dumpFrmCnt= %u, frm_num = %u", dumpFrmCnt, frm_num); 1991 if (dumpFrmCnt < frm_num) { 1992 char timeBuf[128]; 1993 char buf[32]; 1994 memset(buf, 0, sizeof(buf)); 1995 memset(timeBuf, 0, sizeof(timeBuf)); 1996 time_t current_time; 1997 struct tm * timeinfo; 1998 time (¤t_time); 1999 timeinfo = localtime (¤t_time); 2000 if (NULL != timeinfo) { 2001 strftime(timeBuf, sizeof(timeBuf), 2002 QCAMERA_DUMP_FRM_LOCATION "%Y%m%d%H%M%S", timeinfo); 2003 } 2004 String8 filePath(timeBuf); 2005 snprintf(buf, sizeof(buf), "%um_%s_%d.bin", dumpFrmCnt, type, frame->frame_idx); 2006 filePath.append(buf); 2007 int file_fd = open(filePath.string(), O_RDWR | O_CREAT, 0777); 2008 if (file_fd >= 0) { 2009 ssize_t written_len = 0; 2010 metadata->tuning_params.tuning_data_version = TUNING_DATA_VERSION; 2011 void *data = (void *)((uint8_t *)&metadata->tuning_params.tuning_data_version); 2012 written_len += write(file_fd, data, sizeof(uint32_t)); 2013 data = (void *)((uint8_t *)&metadata->tuning_params.tuning_sensor_data_size); 2014 CDBG_HIGH("tuning_sensor_data_size %d",(int)(*(int *)data)); 2015 written_len += write(file_fd, data, sizeof(uint32_t)); 2016 data = (void *)((uint8_t *)&metadata->tuning_params.tuning_vfe_data_size); 2017 CDBG_HIGH("tuning_vfe_data_size %d",(int)(*(int *)data)); 2018 written_len += write(file_fd, data, sizeof(uint32_t)); 2019 data = (void *)((uint8_t *)&metadata->tuning_params.tuning_cpp_data_size); 2020 CDBG_HIGH("tuning_cpp_data_size %d",(int)(*(int *)data)); 2021 written_len += write(file_fd, data, sizeof(uint32_t)); 2022 data = (void *)((uint8_t *)&metadata->tuning_params.tuning_cac_data_size); 2023 CDBG_HIGH("tuning_cac_data_size %d",(int)(*(int *)data)); 2024 written_len += write(file_fd, data, sizeof(uint32_t)); 2025 data = (void *)((uint8_t *)&metadata->tuning_params.tuning_cac_data_size2); 2026 CDBG_HIGH("%s < skrajago >tuning_cac_data_size %d",__func__,(int)(*(int *)data)); 2027 written_len += write(file_fd, data, sizeof(uint32_t)); 2028 size_t total_size = metadata->tuning_params.tuning_sensor_data_size; 2029 data = (void *)((uint8_t *)&metadata->tuning_params.data); 2030 written_len += write(file_fd, data, total_size); 2031 total_size = metadata->tuning_params.tuning_vfe_data_size; 2032 data = (void *)((uint8_t *)&metadata->tuning_params.data[TUNING_VFE_DATA_OFFSET]); 2033 written_len += write(file_fd, data, total_size); 2034 total_size = metadata->tuning_params.tuning_cpp_data_size; 2035 data = (void *)((uint8_t *)&metadata->tuning_params.data[TUNING_CPP_DATA_OFFSET]); 2036 written_len += write(file_fd, data, total_size); 2037 total_size = metadata->tuning_params.tuning_cac_data_size; 2038 data = (void *)((uint8_t *)&metadata->tuning_params.data[TUNING_CAC_DATA_OFFSET]); 2039 written_len += write(file_fd, data, total_size); 2040 close(file_fd); 2041 }else { 2042 ALOGE("%s: fail t open file for image dumping", __func__); 2043 } 2044 dumpFrmCnt++; 2045 } 2046 } 2047 stream->mDumpMetaFrame = dumpFrmCnt; 2048 } 2049 /*=========================================================================== 2050 * FUNCTION : dumpFrameToFile 2051 * 2052 * DESCRIPTION: helper function to dump frame into file for debug purpose. 2053 * 2054 * PARAMETERS : 2055 * @data : data ptr 2056 * @size : length of data buffer 2057 * @index : identifier for data 2058 * @dump_type : type of the frame to be dumped. Only such 2059 * dump type is enabled, the frame will be 2060 * dumped into a file. 2061 * 2062 * RETURN : None 2063 *==========================================================================*/ 2064 void QCamera2HardwareInterface::dumpFrameToFile(QCameraStream *stream, 2065 mm_camera_buf_def_t *frame, uint32_t dump_type) 2066 { 2067 char value[PROPERTY_VALUE_MAX]; 2068 property_get("persist.camera.dumpimg", value, "0"); 2069 uint32_t enabled = (uint32_t) atoi(value); 2070 uint32_t frm_num = 0; 2071 uint32_t skip_mode = 0; 2072 2073 if (NULL == stream) { 2074 ALOGE("%s stream object is null", __func__); 2075 return; 2076 } 2077 2078 uint32_t dumpFrmCnt = stream->mDumpFrame; 2079 2080 if (true == m_bIntRawEvtPending) { 2081 enabled = QCAMERA_DUMP_FRM_RAW; 2082 } 2083 2084 if((enabled & QCAMERA_DUMP_FRM_MASK_ALL)) { 2085 if((enabled & dump_type) && stream && frame) { 2086 frm_num = ((enabled & 0xffff0000) >> 16); 2087 if(frm_num == 0) { 2088 frm_num = 10; //default 10 frames 2089 } 2090 if(frm_num > 256) { 2091 frm_num = 256; //256 buffers cycle around 2092 } 2093 skip_mode = ((enabled & 0x0000ff00) >> 8); 2094 if(skip_mode == 0) { 2095 skip_mode = 1; //no-skip 2096 } 2097 if(stream->mDumpSkipCnt == 0) 2098 stream->mDumpSkipCnt = 1; 2099 2100 if( stream->mDumpSkipCnt % skip_mode == 0) { 2101 if((frm_num == 256) && (dumpFrmCnt >= frm_num)) { 2102 // reset frame count if cycling 2103 dumpFrmCnt = 0; 2104 } 2105 if (dumpFrmCnt <= frm_num) { 2106 char buf[32]; 2107 char timeBuf[128]; 2108 time_t current_time; 2109 struct tm * timeinfo; 2110 2111 memset(timeBuf, 0, sizeof(timeBuf)); 2112 2113 time (¤t_time); 2114 timeinfo = localtime (¤t_time); 2115 memset(buf, 0, sizeof(buf)); 2116 2117 cam_dimension_t dim; 2118 memset(&dim, 0, sizeof(dim)); 2119 stream->getFrameDimension(dim); 2120 2121 cam_frame_len_offset_t offset; 2122 memset(&offset, 0, sizeof(cam_frame_len_offset_t)); 2123 stream->getFrameOffset(offset); 2124 2125 if (NULL != timeinfo) { 2126 strftime(timeBuf, sizeof(timeBuf), 2127 QCAMERA_DUMP_FRM_LOCATION "%Y%m%d%H%M%S", timeinfo); 2128 } 2129 String8 filePath(timeBuf); 2130 switch (dump_type) { 2131 case QCAMERA_DUMP_FRM_PREVIEW: 2132 { 2133 snprintf(buf, sizeof(buf), "%dp_%dx%d_%d.yuv", 2134 dumpFrmCnt, dim.width, dim.height, frame->frame_idx); 2135 } 2136 break; 2137 case QCAMERA_DUMP_FRM_THUMBNAIL: 2138 { 2139 snprintf(buf, sizeof(buf), "%dt_%dx%d_%d.yuv", 2140 dumpFrmCnt, dim.width, dim.height, frame->frame_idx); 2141 } 2142 break; 2143 case QCAMERA_DUMP_FRM_SNAPSHOT: 2144 { 2145 mParameters.getStreamDimension(CAM_STREAM_TYPE_SNAPSHOT, dim); 2146 snprintf(buf, sizeof(buf), "%ds_%dx%d_%d.yuv", 2147 dumpFrmCnt, dim.width, dim.height, frame->frame_idx); 2148 } 2149 break; 2150 case QCAMERA_DUMP_FRM_VIDEO: 2151 { 2152 snprintf(buf, sizeof(buf), "%dv_%dx%d_%d.yuv", 2153 dumpFrmCnt, dim.width, dim.height, frame->frame_idx); 2154 } 2155 break; 2156 case QCAMERA_DUMP_FRM_RAW: 2157 { 2158 mParameters.getStreamDimension(CAM_STREAM_TYPE_RAW, dim); 2159 snprintf(buf, sizeof(buf), "%dr_%dx%d_%d.raw", 2160 dumpFrmCnt, dim.width, dim.height, frame->frame_idx); 2161 } 2162 break; 2163 case QCAMERA_DUMP_FRM_JPEG: 2164 { 2165 mParameters.getStreamDimension(CAM_STREAM_TYPE_SNAPSHOT, dim); 2166 snprintf(buf, sizeof(buf), "%dj_%dx%d_%d.yuv", 2167 dumpFrmCnt, dim.width, dim.height, frame->frame_idx); 2168 } 2169 break; 2170 default: 2171 ALOGE("%s: Not supported for dumping stream type %d", 2172 __func__, dump_type); 2173 return; 2174 } 2175 2176 filePath.append(buf); 2177 int file_fd = open(filePath.string(), O_RDWR | O_CREAT, 0777); 2178 ssize_t written_len = 0; 2179 if (file_fd >= 0) { 2180 void *data = NULL; 2181 2182 fchmod(file_fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 2183 for (uint32_t i = 0; i < offset.num_planes; i++) { 2184 uint32_t index = offset.mp[i].offset; 2185 if (i > 0) { 2186 index += offset.mp[i-1].len; 2187 } 2188 for (int j = 0; j < offset.mp[i].height; j++) { 2189 data = (void *)((uint8_t *)frame->buffer + index); 2190 written_len += write(file_fd, data, 2191 (size_t)offset.mp[i].width); 2192 index += (uint32_t)offset.mp[i].stride; 2193 } 2194 } 2195 2196 CDBG_HIGH("%s: written number of bytes %zd\n", 2197 __func__, written_len); 2198 close(file_fd); 2199 } else { 2200 ALOGE("%s: fail t open file for image dumping", __func__); 2201 } 2202 if (true == m_bIntRawEvtPending) { 2203 strlcpy(m_BackendFileName, filePath.string(), QCAMERA_MAX_FILEPATH_LENGTH); 2204 mBackendFileSize = (size_t)written_len; 2205 } else { 2206 dumpFrmCnt++; 2207 } 2208 } 2209 } 2210 stream->mDumpSkipCnt++; 2211 } 2212 } else { 2213 dumpFrmCnt = 0; 2214 } 2215 stream->mDumpFrame = dumpFrmCnt; 2216 } 2217 2218 /*=========================================================================== 2219 * FUNCTION : debugShowVideoFPS 2220 * 2221 * DESCRIPTION: helper function to log video frame FPS for debug purpose. 2222 * 2223 * PARAMETERS : None 2224 * 2225 * RETURN : None 2226 *==========================================================================*/ 2227 void QCamera2HardwareInterface::debugShowVideoFPS() 2228 { 2229 mVFrameCount++; 2230 nsecs_t now = systemTime(); 2231 nsecs_t diff = now - mVLastFpsTime; 2232 if (diff > ms2ns(250)) { 2233 mVFps = (((double)(mVFrameCount - mVLastFrameCount)) * 2234 (double)(s2ns(1))) / (double)diff; 2235 CDBG_HIGH("Video Frames Per Second: %.4f Cam ID = %d", mVFps, mCameraId); 2236 mVLastFpsTime = now; 2237 mVLastFrameCount = mVFrameCount; 2238 } 2239 } 2240 2241 /*=========================================================================== 2242 * FUNCTION : debugShowPreviewFPS 2243 * 2244 * DESCRIPTION: helper function to log preview frame FPS for debug purpose. 2245 * 2246 * PARAMETERS : None 2247 * 2248 * RETURN : None 2249 *==========================================================================*/ 2250 void QCamera2HardwareInterface::debugShowPreviewFPS() 2251 { 2252 mPFrameCount++; 2253 nsecs_t now = systemTime(); 2254 nsecs_t diff = now - mPLastFpsTime; 2255 if (diff > ms2ns(250)) { 2256 mPFps = (((double)(mPFrameCount - mPLastFrameCount)) * 2257 (double)(s2ns(1))) / (double)diff; 2258 CDBG_HIGH("[KPI Perf] %s: PROFILE_PREVIEW_FRAMES_PER_SECOND : %.4f Cam ID = %d", 2259 __func__, mPFps, mCameraId); 2260 mPLastFpsTime = now; 2261 mPLastFrameCount = mPFrameCount; 2262 } 2263 } 2264 2265 /*=========================================================================== 2266 * FUNCTION : ~QCameraCbNotifier 2267 * 2268 * DESCRIPTION: Destructor for exiting the callback context. 2269 * 2270 * PARAMETERS : None 2271 * 2272 * RETURN : None 2273 *==========================================================================*/ 2274 QCameraCbNotifier::~QCameraCbNotifier() 2275 { 2276 } 2277 2278 /*=========================================================================== 2279 * FUNCTION : exit 2280 * 2281 * DESCRIPTION: exit notify thread. 2282 * 2283 * PARAMETERS : None 2284 * 2285 * RETURN : None 2286 *==========================================================================*/ 2287 void QCameraCbNotifier::exit() 2288 { 2289 mActive = false; 2290 mProcTh.exit(); 2291 } 2292 2293 /*=========================================================================== 2294 * FUNCTION : releaseNotifications 2295 * 2296 * DESCRIPTION: callback for releasing data stored in the callback queue. 2297 * 2298 * PARAMETERS : 2299 * @data : data to be released 2300 * @user_data : context data 2301 * 2302 * RETURN : None 2303 *==========================================================================*/ 2304 void QCameraCbNotifier::releaseNotifications(void *data, void *user_data) 2305 { 2306 qcamera_callback_argm_t *arg = ( qcamera_callback_argm_t * ) data; 2307 2308 if ( ( NULL != arg ) && ( NULL != user_data ) ) { 2309 if ( arg->release_cb ) { 2310 arg->release_cb(arg->user_data, arg->cookie, FAILED_TRANSACTION); 2311 } 2312 } 2313 } 2314 2315 /*=========================================================================== 2316 * FUNCTION : matchSnapshotNotifications 2317 * 2318 * DESCRIPTION: matches snapshot data callbacks 2319 * 2320 * PARAMETERS : 2321 * @data : data to match 2322 * @user_data : context data 2323 * 2324 * RETURN : bool match 2325 * true - match found 2326 * false- match not found 2327 *==========================================================================*/ 2328 bool QCameraCbNotifier::matchSnapshotNotifications(void *data, 2329 void */*user_data*/) 2330 { 2331 qcamera_callback_argm_t *arg = ( qcamera_callback_argm_t * ) data; 2332 if ( NULL != arg ) { 2333 if ( QCAMERA_DATA_SNAPSHOT_CALLBACK == arg->cb_type ) { 2334 return true; 2335 } 2336 } 2337 2338 return false; 2339 } 2340 2341 /*=========================================================================== 2342 * FUNCTION : matchPreviewNotifications 2343 * 2344 * DESCRIPTION: matches preview data callbacks 2345 * 2346 * PARAMETERS : 2347 * @data : data to match 2348 * @user_data : context data 2349 * 2350 * RETURN : bool match 2351 * true - match found 2352 * false- match not found 2353 *==========================================================================*/ 2354 bool QCameraCbNotifier::matchPreviewNotifications(void *data, 2355 void */*user_data*/) 2356 { 2357 qcamera_callback_argm_t *arg = ( qcamera_callback_argm_t * ) data; 2358 if (NULL != arg) { 2359 if ((QCAMERA_DATA_CALLBACK == arg->cb_type) && 2360 (CAMERA_MSG_PREVIEW_FRAME == arg->msg_type)) { 2361 return true; 2362 } 2363 } 2364 2365 return false; 2366 } 2367 2368 /*=========================================================================== 2369 * FUNCTION : cbNotifyRoutine 2370 * 2371 * DESCRIPTION: callback thread which interfaces with the upper layers 2372 * given input commands. 2373 * 2374 * PARAMETERS : 2375 * @data : context data 2376 * 2377 * RETURN : None 2378 *==========================================================================*/ 2379 void * QCameraCbNotifier::cbNotifyRoutine(void * data) 2380 { 2381 int running = 1; 2382 int ret; 2383 QCameraCbNotifier *pme = (QCameraCbNotifier *)data; 2384 QCameraCmdThread *cmdThread = &pme->mProcTh; 2385 cmdThread->setName("CAM_cbNotify"); 2386 uint8_t isSnapshotActive = FALSE; 2387 bool longShotEnabled = false; 2388 uint32_t numOfSnapshotExpected = 0; 2389 uint32_t numOfSnapshotRcvd = 0; 2390 int32_t cbStatus = NO_ERROR; 2391 2392 CDBG("%s: E", __func__); 2393 do { 2394 do { 2395 ret = cam_sem_wait(&cmdThread->cmd_sem); 2396 if (ret != 0 && errno != EINVAL) { 2397 CDBG("%s: cam_sem_wait error (%s)", 2398 __func__, strerror(errno)); 2399 return NULL; 2400 } 2401 } while (ret != 0); 2402 2403 camera_cmd_type_t cmd = cmdThread->getCmd(); 2404 CDBG("%s: get cmd %d", __func__, cmd); 2405 switch (cmd) { 2406 case CAMERA_CMD_TYPE_START_DATA_PROC: 2407 { 2408 isSnapshotActive = TRUE; 2409 numOfSnapshotExpected = pme->mParent->numOfSnapshotsExpected(); 2410 longShotEnabled = pme->mParent->isLongshotEnabled(); 2411 ALOGI("%s: Num Snapshots Expected = %d", 2412 __func__, numOfSnapshotExpected); 2413 numOfSnapshotRcvd = 0; 2414 } 2415 break; 2416 case CAMERA_CMD_TYPE_STOP_DATA_PROC: 2417 { 2418 pme->mDataQ.flushNodes(matchSnapshotNotifications); 2419 isSnapshotActive = FALSE; 2420 2421 numOfSnapshotExpected = 0; 2422 numOfSnapshotRcvd = 0; 2423 } 2424 break; 2425 case CAMERA_CMD_TYPE_DO_NEXT_JOB: 2426 { 2427 qcamera_callback_argm_t *cb = 2428 (qcamera_callback_argm_t *)pme->mDataQ.dequeue(); 2429 cbStatus = NO_ERROR; 2430 if (NULL != cb) { 2431 CDBG("%s: cb type %d received", 2432 __func__, 2433 cb->cb_type); 2434 2435 if (pme->mParent->msgTypeEnabledWithLock(cb->msg_type)) { 2436 switch (cb->cb_type) { 2437 case QCAMERA_NOTIFY_CALLBACK: 2438 { 2439 if (cb->msg_type == CAMERA_MSG_FOCUS) { 2440 ATRACE_INT("Camera:AutoFocus", 0); 2441 CDBG_HIGH("[KPI Perf] %s : PROFILE_SENDING_FOCUS_EVT_TO APP", 2442 __func__); 2443 } 2444 if (pme->mNotifyCb) { 2445 pme->mNotifyCb(cb->msg_type, 2446 cb->ext1, 2447 cb->ext2, 2448 pme->mCallbackCookie); 2449 } else { 2450 ALOGE("%s : notify callback not set!", 2451 __func__); 2452 } 2453 } 2454 break; 2455 case QCAMERA_DATA_CALLBACK: 2456 { 2457 if (pme->mDataCb) { 2458 pme->mDataCb(cb->msg_type, 2459 cb->data, 2460 cb->index, 2461 cb->metadata, 2462 pme->mCallbackCookie); 2463 } else { 2464 ALOGE("%s : data callback not set!", 2465 __func__); 2466 } 2467 } 2468 break; 2469 case QCAMERA_DATA_TIMESTAMP_CALLBACK: 2470 { 2471 if(pme->mDataCbTimestamp) { 2472 pme->mDataCbTimestamp(cb->timestamp, 2473 cb->msg_type, 2474 cb->data, 2475 cb->index, 2476 pme->mCallbackCookie); 2477 } else { 2478 ALOGE("%s:data cb with tmp not set!", 2479 __func__); 2480 } 2481 } 2482 break; 2483 case QCAMERA_DATA_SNAPSHOT_CALLBACK: 2484 { 2485 if (TRUE == isSnapshotActive && pme->mDataCb ) { 2486 if (!longShotEnabled) { 2487 numOfSnapshotRcvd++; 2488 ALOGI("%s: [ZSL Retro] Num Snapshots Received = %d", __func__, 2489 numOfSnapshotRcvd); 2490 if (numOfSnapshotExpected > 0 && 2491 (numOfSnapshotExpected == numOfSnapshotRcvd)) { 2492 ALOGI("%s: [ZSL Retro] Expected snapshot received = %d", 2493 __func__, numOfSnapshotRcvd); 2494 // notify HWI that snapshot is done 2495 pme->mParent->processSyncEvt(QCAMERA_SM_EVT_SNAPSHOT_DONE, 2496 NULL); 2497 } 2498 } 2499 pme->mDataCb(cb->msg_type, 2500 cb->data, 2501 cb->index, 2502 cb->metadata, 2503 pme->mCallbackCookie); 2504 } 2505 } 2506 break; 2507 default: 2508 { 2509 ALOGE("%s : invalid cb type %d", 2510 __func__, 2511 cb->cb_type); 2512 cbStatus = BAD_VALUE; 2513 } 2514 break; 2515 }; 2516 } else { 2517 ALOGE("%s : cb message type %d not enabled!", 2518 __func__, 2519 cb->msg_type); 2520 cbStatus = INVALID_OPERATION; 2521 } 2522 if ( cb->release_cb ) { 2523 cb->release_cb(cb->user_data, cb->cookie, cbStatus); 2524 } 2525 delete cb; 2526 } else { 2527 ALOGE("%s: invalid cb type passed", __func__); 2528 } 2529 } 2530 break; 2531 case CAMERA_CMD_TYPE_EXIT: 2532 { 2533 running = 0; 2534 pme->mDataQ.flush(); 2535 } 2536 break; 2537 default: 2538 break; 2539 } 2540 } while (running); 2541 CDBG("%s: X", __func__); 2542 2543 return NULL; 2544 } 2545 2546 /*=========================================================================== 2547 * FUNCTION : notifyCallback 2548 * 2549 * DESCRIPTION: Enqueus pending callback notifications for the upper layers. 2550 * 2551 * PARAMETERS : 2552 * @cbArgs : callback arguments 2553 * 2554 * RETURN : int32_t type of status 2555 * NO_ERROR -- success 2556 * none-zero failure code 2557 *==========================================================================*/ 2558 int32_t QCameraCbNotifier::notifyCallback(qcamera_callback_argm_t &cbArgs) 2559 { 2560 if (!mActive) { 2561 ALOGE("%s: notify thread is not active", __func__); 2562 return UNKNOWN_ERROR; 2563 } 2564 2565 qcamera_callback_argm_t *cbArg = new qcamera_callback_argm_t(); 2566 if (NULL == cbArg) { 2567 ALOGE("%s: no mem for qcamera_callback_argm_t", __func__); 2568 return NO_MEMORY; 2569 } 2570 memset(cbArg, 0, sizeof(qcamera_callback_argm_t)); 2571 *cbArg = cbArgs; 2572 2573 if (mDataQ.enqueue((void *)cbArg)) { 2574 return mProcTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE); 2575 } else { 2576 ALOGE("%s: Error adding cb data into queue", __func__); 2577 delete cbArg; 2578 return UNKNOWN_ERROR; 2579 } 2580 } 2581 2582 /*=========================================================================== 2583 * FUNCTION : setCallbacks 2584 * 2585 * DESCRIPTION: Initializes the callback functions, which would be used for 2586 * communication with the upper layers and launches the callback 2587 * context in which the callbacks will occur. 2588 * 2589 * PARAMETERS : 2590 * @notifyCb : notification callback 2591 * @dataCb : data callback 2592 * @dataCbTimestamp : data with timestamp callback 2593 * @callbackCookie : callback context data 2594 * 2595 * RETURN : None 2596 *==========================================================================*/ 2597 void QCameraCbNotifier::setCallbacks(camera_notify_callback notifyCb, 2598 camera_data_callback dataCb, 2599 camera_data_timestamp_callback dataCbTimestamp, 2600 void *callbackCookie) 2601 { 2602 if ( ( NULL == mNotifyCb ) && 2603 ( NULL == mDataCb ) && 2604 ( NULL == mDataCbTimestamp ) && 2605 ( NULL == mCallbackCookie ) ) { 2606 mNotifyCb = notifyCb; 2607 mDataCb = dataCb; 2608 mDataCbTimestamp = dataCbTimestamp; 2609 mCallbackCookie = callbackCookie; 2610 mActive = true; 2611 mProcTh.launch(cbNotifyRoutine, this); 2612 } else { 2613 ALOGE("%s : Camera callback notifier already initialized!", 2614 __func__); 2615 } 2616 } 2617 2618 /*=========================================================================== 2619 * FUNCTION : flushPreviewNotifications 2620 * 2621 * DESCRIPTION: flush all pending preview notifications 2622 * from the notifier queue 2623 * 2624 * PARAMETERS : None 2625 * 2626 * RETURN : int32_t type of status 2627 * NO_ERROR -- success 2628 * none-zero failure code 2629 *==========================================================================*/ 2630 int32_t QCameraCbNotifier::flushPreviewNotifications() 2631 { 2632 if (!mActive) { 2633 ALOGE("%s: notify thread is not active", __func__); 2634 return UNKNOWN_ERROR; 2635 } 2636 2637 mDataQ.flushNodes(matchPreviewNotifications); 2638 2639 return NO_ERROR; 2640 } 2641 2642 /*=========================================================================== 2643 * FUNCTION : startSnapshots 2644 * 2645 * DESCRIPTION: Enables snapshot mode 2646 * 2647 * PARAMETERS : None 2648 * 2649 * RETURN : int32_t type of status 2650 * NO_ERROR -- success 2651 * none-zero failure code 2652 *==========================================================================*/ 2653 int32_t QCameraCbNotifier::startSnapshots() 2654 { 2655 return mProcTh.sendCmd(CAMERA_CMD_TYPE_START_DATA_PROC, FALSE, TRUE); 2656 } 2657 2658 /*=========================================================================== 2659 * FUNCTION : stopSnapshots 2660 * 2661 * DESCRIPTION: Disables snapshot processing mode 2662 * 2663 * PARAMETERS : None 2664 * 2665 * RETURN : None 2666 *==========================================================================*/ 2667 void QCameraCbNotifier::stopSnapshots() 2668 { 2669 mProcTh.sendCmd(CAMERA_CMD_TYPE_STOP_DATA_PROC, FALSE, TRUE); 2670 } 2671 2672 }; // namespace qcamera 2673