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 // Sharpness 1438 cam_edge_application_t edge_application; 1439 memset(&edge_application, 0x00, sizeof(cam_edge_application_t)); 1440 edge_application.sharpness = mParameters.getSharpness(); 1441 if (edge_application.sharpness != 0) { 1442 edge_application.edge_mode = CAM_EDGE_MODE_FAST; 1443 } else { 1444 edge_application.edge_mode = CAM_EDGE_MODE_OFF; 1445 } 1446 ADD_SET_PARAM_ENTRY_TO_BATCH(pMetaData, 1447 CAM_INTF_META_EDGE_MODE, edge_application); 1448 1449 //Effect 1450 int32_t prmEffect = mParameters.getEffect(); 1451 ADD_SET_PARAM_ENTRY_TO_BATCH(pMetaData, CAM_INTF_PARM_EFFECT, prmEffect); 1452 1453 //flip 1454 int32_t prmFlip = mParameters.getFlipMode(CAM_STREAM_TYPE_SNAPSHOT); 1455 ADD_SET_PARAM_ENTRY_TO_BATCH(pMetaData, CAM_INTF_PARM_FLIP, prmFlip); 1456 1457 //denoise 1458 uint8_t prmDenoise = (uint8_t)mParameters.isWNREnabled(); 1459 ADD_SET_PARAM_ENTRY_TO_BATCH(pMetaData, 1460 CAM_INTF_META_NOISE_REDUCTION_MODE, prmDenoise); 1461 1462 //rotation & device rotation 1463 uint32_t prmRotation = mParameters.getJpegRotation(); 1464 cam_rotation_info_t rotation_info; 1465 if (prmRotation == 0) { 1466 rotation_info.rotation = ROTATE_0; 1467 } else if (prmRotation == 90) { 1468 rotation_info.rotation = ROTATE_90; 1469 } else if (prmRotation == 180) { 1470 rotation_info.rotation = ROTATE_180; 1471 } else if (prmRotation == 270) { 1472 rotation_info.rotation = ROTATE_270; 1473 } 1474 1475 uint32_t device_rotation = mParameters.getDeviceRotation(); 1476 if (device_rotation == 0) { 1477 rotation_info.device_rotation = ROTATE_0; 1478 } else if (device_rotation == 90) { 1479 rotation_info.device_rotation = ROTATE_90; 1480 } else if (device_rotation == 180) { 1481 rotation_info.device_rotation = ROTATE_180; 1482 } else if (device_rotation == 270) { 1483 rotation_info.device_rotation = ROTATE_270; 1484 } else { 1485 rotation_info.device_rotation = ROTATE_0; 1486 } 1487 ADD_SET_PARAM_ENTRY_TO_BATCH(pMetaData, CAM_INTF_PARM_ROTATION, rotation_info); 1488 1489 return rc; 1490 } 1491 1492 /*=========================================================================== 1493 * FUNCTION : metadata_stream_cb_routine 1494 * 1495 * DESCRIPTION: helper function to handle metadata frame from metadata stream 1496 * 1497 * PARAMETERS : 1498 * @super_frame : received super buffer 1499 * @stream : stream object 1500 * @userdata : user data ptr 1501 * 1502 * RETURN : None 1503 * 1504 * NOTE : caller passes the ownership of super_frame, it's our 1505 * responsibility to free super_frame once it's done. Metadata 1506 * could have valid entries for face detection result or 1507 * histogram statistics information. 1508 *==========================================================================*/ 1509 void QCamera2HardwareInterface::metadata_stream_cb_routine(mm_camera_super_buf_t * super_frame, 1510 QCameraStream * stream, 1511 void * userdata) 1512 { 1513 ATRACE_CALL(); 1514 CDBG("[KPI Perf] %s : BEGIN", __func__); 1515 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 1516 if (pme == NULL || 1517 pme->mCameraHandle == NULL || 1518 pme->mCameraHandle->camera_handle != super_frame->camera_handle){ 1519 ALOGE("%s: camera obj not valid", __func__); 1520 // simply free super frame 1521 free(super_frame); 1522 return; 1523 } 1524 1525 mm_camera_buf_def_t *frame = super_frame->bufs[0]; 1526 metadata_buffer_t *pMetaData = (metadata_buffer_t *)frame->buffer; 1527 if(pme->m_stateMachine.isNonZSLCaptureRunning()&& 1528 !pme->mLongshotEnabled) { 1529 //Make shutter call back in non ZSL mode once raw frame is received from VFE. 1530 pme->playShutter(); 1531 } 1532 1533 if (pMetaData->is_tuning_params_valid && pme->mParameters.getRecordingHintValue() == true) { 1534 //Dump Tuning data for video 1535 pme->dumpMetadataToFile(stream,frame,(char *)"Video"); 1536 } 1537 1538 IF_META_AVAILABLE(cam_hist_stats_t, stats_data, CAM_INTF_META_HISTOGRAM, pMetaData) { 1539 // process histogram statistics info 1540 qcamera_sm_internal_evt_payload_t *payload = 1541 (qcamera_sm_internal_evt_payload_t *) 1542 malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 1543 if (NULL != payload) { 1544 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 1545 payload->evt_type = QCAMERA_INTERNAL_EVT_HISTOGRAM_STATS; 1546 payload->stats_data = *stats_data; 1547 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 1548 if (rc != NO_ERROR) { 1549 ALOGE("%s: processEvt histogram failed", __func__); 1550 free(payload); 1551 payload = NULL; 1552 1553 } 1554 } else { 1555 ALOGE("%s: No memory for histogram qcamera_sm_internal_evt_payload_t", __func__); 1556 } 1557 } 1558 1559 IF_META_AVAILABLE(cam_face_detection_data_t, faces_data, 1560 CAM_INTF_META_FACE_DETECTION, pMetaData) { 1561 if (faces_data->num_faces_detected > MAX_ROI) { 1562 ALOGE("%s: Invalid number of faces %d", 1563 __func__, faces_data->num_faces_detected); 1564 } else { 1565 // process face detection result 1566 if (faces_data->num_faces_detected) 1567 CDBG_HIGH("[KPI Perf] %s: PROFILE_NUMBER_OF_FACES_DETECTED %d", 1568 __func__,faces_data->num_faces_detected); 1569 faces_data->fd_type = QCAMERA_FD_PREVIEW; //HARD CODE here before MCT can support 1570 qcamera_sm_internal_evt_payload_t *payload = (qcamera_sm_internal_evt_payload_t *) 1571 malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 1572 if (NULL != payload) { 1573 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 1574 payload->evt_type = QCAMERA_INTERNAL_EVT_FACE_DETECT_RESULT; 1575 payload->faces_data = *faces_data; 1576 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 1577 if (rc != NO_ERROR) { 1578 ALOGE("%s: processEvt face detection failed", __func__); 1579 free(payload); 1580 payload = NULL; 1581 } 1582 } else { 1583 ALOGE("%s: No memory for face detect qcamera_sm_internal_evt_payload_t", __func__); 1584 } 1585 } 1586 } 1587 1588 IF_META_AVAILABLE(cam_auto_focus_data_t, focus_data, 1589 CAM_INTF_META_AUTOFOCUS_DATA, pMetaData) { 1590 qcamera_sm_internal_evt_payload_t *payload = 1591 (qcamera_sm_internal_evt_payload_t *)malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 1592 if (NULL != payload) { 1593 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 1594 payload->evt_type = QCAMERA_INTERNAL_EVT_FOCUS_UPDATE; 1595 payload->focus_data = *focus_data; 1596 payload->focus_data.focused_frame_idx = frame->frame_idx; 1597 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 1598 if (rc != NO_ERROR) { 1599 ALOGE("%s: processEvt focus failed", __func__); 1600 free(payload); 1601 payload = NULL; 1602 1603 } 1604 } else { 1605 ALOGE("%s: No memory for focus qcamera_sm_internal_evt_payload_t", __func__); 1606 } 1607 } 1608 1609 IF_META_AVAILABLE(cam_crop_data_t, crop_data, CAM_INTF_META_CROP_DATA, pMetaData) { 1610 if (crop_data->num_of_streams > MAX_NUM_STREAMS) { 1611 ALOGE("%s: Invalid num_of_streams %d in crop_data", __func__, 1612 crop_data->num_of_streams); 1613 } else { 1614 qcamera_sm_internal_evt_payload_t *payload = 1615 (qcamera_sm_internal_evt_payload_t *) 1616 malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 1617 if (NULL != payload) { 1618 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 1619 payload->evt_type = QCAMERA_INTERNAL_EVT_CROP_INFO; 1620 payload->crop_data = *crop_data; 1621 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 1622 if (rc != NO_ERROR) { 1623 ALOGE("%s: processEvt crop info failed", __func__); 1624 free(payload); 1625 payload = NULL; 1626 1627 } 1628 } else { 1629 ALOGE("%s: No memory for prep_snapshot qcamera_sm_internal_evt_payload_t", 1630 __func__); 1631 } 1632 } 1633 } 1634 1635 IF_META_AVAILABLE(int32_t, prep_snapshot_done_state, 1636 CAM_INTF_META_PREP_SNAPSHOT_DONE, pMetaData) { 1637 qcamera_sm_internal_evt_payload_t *payload = 1638 (qcamera_sm_internal_evt_payload_t *)malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 1639 if (NULL != payload) { 1640 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 1641 payload->evt_type = QCAMERA_INTERNAL_EVT_PREP_SNAPSHOT_DONE; 1642 payload->prep_snapshot_state = (cam_prep_snapshot_state_t)*prep_snapshot_done_state; 1643 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 1644 if (rc != NO_ERROR) { 1645 ALOGE("%s: processEvt prep_snapshot failed", __func__); 1646 free(payload); 1647 payload = NULL; 1648 1649 } 1650 } else { 1651 ALOGE("%s: No memory for prep_snapshot qcamera_sm_internal_evt_payload_t", __func__); 1652 } 1653 } 1654 1655 IF_META_AVAILABLE(cam_asd_hdr_scene_data_t, hdr_scene_data, 1656 CAM_INTF_META_ASD_HDR_SCENE_DATA, pMetaData) { 1657 CDBG_HIGH("%s: hdr_scene_data: %d %f\n", __func__, 1658 hdr_scene_data->is_hdr_scene, hdr_scene_data->hdr_confidence); 1659 //Handle this HDR meta data only if capture is not in process 1660 if (!pme->m_stateMachine.isCaptureRunning()) { 1661 qcamera_sm_internal_evt_payload_t *payload = 1662 (qcamera_sm_internal_evt_payload_t *) 1663 malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 1664 if (NULL != payload) { 1665 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 1666 payload->evt_type = QCAMERA_INTERNAL_EVT_HDR_UPDATE; 1667 payload->hdr_data = *hdr_scene_data; 1668 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 1669 if (rc != NO_ERROR) { 1670 ALOGE("%s: processEvt hdr update failed", __func__); 1671 free(payload); 1672 payload = NULL; 1673 } 1674 } else { 1675 ALOGE("%s: No memory for hdr update qcamera_sm_internal_evt_payload_t", 1676 __func__); 1677 } 1678 } 1679 } 1680 1681 IF_META_AVAILABLE(int32_t, scene, CAM_INTF_META_ASD_SCENE_TYPE, pMetaData) { 1682 qcamera_sm_internal_evt_payload_t *payload = 1683 (qcamera_sm_internal_evt_payload_t *)malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 1684 if (NULL != payload) { 1685 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 1686 payload->evt_type = QCAMERA_INTERNAL_EVT_ASD_UPDATE; 1687 payload->asd_data = (cam_auto_scene_t)*scene; 1688 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 1689 if (rc != NO_ERROR) { 1690 ALOGE("%s: processEvt asd_update failed", __func__); 1691 free(payload); 1692 payload = NULL; 1693 } 1694 } else { 1695 ALOGE("%s: No memory for asd_update qcamera_sm_internal_evt_payload_t", __func__); 1696 } 1697 } 1698 1699 IF_META_AVAILABLE(cam_awb_params_t, awb_params, CAM_INTF_META_AWB_INFO, pMetaData) { 1700 CDBG_HIGH("%s, metadata for awb params.", __func__); 1701 qcamera_sm_internal_evt_payload_t *payload = 1702 (qcamera_sm_internal_evt_payload_t *) 1703 malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 1704 if (NULL != payload) { 1705 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 1706 payload->evt_type = QCAMERA_INTERNAL_EVT_AWB_UPDATE; 1707 payload->awb_data = *awb_params; 1708 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 1709 if (rc != NO_ERROR) { 1710 ALOGE("%s: processEvt awb_update failed", __func__); 1711 free(payload); 1712 payload = NULL; 1713 } 1714 } else { 1715 ALOGE("%s: No memory for awb_update qcamera_sm_internal_evt_payload_t", __func__); 1716 } 1717 } 1718 1719 IF_META_AVAILABLE(uint32_t, flash_mode, CAM_INTF_META_FLASH_MODE, pMetaData) { 1720 pme->mExifParams.sensor_params.flash_mode = (cam_flash_mode_t)*flash_mode; 1721 } 1722 1723 IF_META_AVAILABLE(int32_t, flash_state, CAM_INTF_META_FLASH_STATE, pMetaData) { 1724 pme->mExifParams.sensor_params.flash_state = (cam_flash_state_t) *flash_state; 1725 } 1726 1727 IF_META_AVAILABLE(float, aperture_value, CAM_INTF_META_LENS_APERTURE, pMetaData) { 1728 pme->mExifParams.sensor_params.aperture_value = *aperture_value; 1729 } 1730 1731 IF_META_AVAILABLE(cam_3a_params_t, ae_params, CAM_INTF_META_AEC_INFO, pMetaData) { 1732 pme->mExifParams.cam_3a_params = *ae_params; 1733 pme->mExifParams.cam_3a_params_valid = TRUE; 1734 pme->mFlashNeeded = ae_params->flash_needed; 1735 pme->mExifParams.cam_3a_params.brightness = (float) pme->mParameters.getBrightness(); 1736 qcamera_sm_internal_evt_payload_t *payload = 1737 (qcamera_sm_internal_evt_payload_t *) 1738 malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 1739 if (NULL != payload) { 1740 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 1741 payload->evt_type = QCAMERA_INTERNAL_EVT_AE_UPDATE; 1742 payload->ae_data = *ae_params; 1743 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 1744 if (rc != NO_ERROR) { 1745 ALOGE("%s: processEvt ae_update failed", __func__); 1746 free(payload); 1747 payload = NULL; 1748 } 1749 } else { 1750 ALOGE("%s: No memory for ae_update qcamera_sm_internal_evt_payload_t", __func__); 1751 } 1752 } 1753 1754 IF_META_AVAILABLE(int32_t, wb_mode, CAM_INTF_PARM_WHITE_BALANCE, pMetaData) { 1755 pme->mExifParams.cam_3a_params.wb_mode = (cam_wb_mode_type) *wb_mode; 1756 } 1757 1758 IF_META_AVAILABLE(cam_sensor_params_t, sensor_params, CAM_INTF_META_SENSOR_INFO, pMetaData) { 1759 pme->mExifParams.sensor_params = *sensor_params; 1760 } 1761 1762 IF_META_AVAILABLE(cam_ae_exif_debug_t, ae_exif_debug_params, 1763 CAM_INTF_META_EXIF_DEBUG_AE, pMetaData) { 1764 pme->mExifParams.ae_debug_params = *ae_exif_debug_params; 1765 pme->mExifParams.ae_debug_params_valid = TRUE; 1766 } 1767 1768 IF_META_AVAILABLE(cam_awb_exif_debug_t, awb_exif_debug_params, 1769 CAM_INTF_META_EXIF_DEBUG_AWB, pMetaData) { 1770 pme->mExifParams.awb_debug_params = *awb_exif_debug_params; 1771 pme->mExifParams.awb_debug_params_valid = TRUE; 1772 } 1773 1774 IF_META_AVAILABLE(cam_af_exif_debug_t, af_exif_debug_params, 1775 CAM_INTF_META_EXIF_DEBUG_AF, pMetaData) { 1776 pme->mExifParams.af_debug_params = *af_exif_debug_params; 1777 pme->mExifParams.af_debug_params_valid = TRUE; 1778 } 1779 1780 IF_META_AVAILABLE(cam_asd_exif_debug_t, asd_exif_debug_params, 1781 CAM_INTF_META_EXIF_DEBUG_ASD, pMetaData) { 1782 pme->mExifParams.asd_debug_params = *asd_exif_debug_params; 1783 pme->mExifParams.asd_debug_params_valid = TRUE; 1784 } 1785 1786 IF_META_AVAILABLE(cam_stats_buffer_exif_debug_t, stats_exif_debug_params, 1787 CAM_INTF_META_EXIF_DEBUG_STATS, pMetaData) { 1788 pme->mExifParams.stats_debug_params = *stats_exif_debug_params; 1789 pme->mExifParams.stats_debug_params_valid = TRUE; 1790 } 1791 1792 IF_META_AVAILABLE(uint32_t, led_mode, CAM_INTF_META_LED_MODE_OVERRIDE, pMetaData) { 1793 qcamera_sm_internal_evt_payload_t *payload = 1794 (qcamera_sm_internal_evt_payload_t *) 1795 malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 1796 if (NULL != payload) { 1797 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 1798 payload->evt_type = QCAMERA_INTERNAL_EVT_LED_MODE_OVERRIDE; 1799 payload->led_data = (cam_flash_mode_t)*led_mode; 1800 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 1801 if (rc != NO_ERROR) { 1802 ALOGE("%s: processEvt led mode override failed", __func__); 1803 free(payload); 1804 payload = NULL; 1805 } 1806 } else { 1807 ALOGE("%s: No memory for focus qcamera_sm_internal_evt_payload_t", __func__); 1808 } 1809 } 1810 1811 cam_edge_application_t edge_application; 1812 memset(&edge_application, 0x00, sizeof(cam_edge_application_t)); 1813 edge_application.sharpness = pme->mParameters.getSharpness(); 1814 if (edge_application.sharpness != 0) { 1815 edge_application.edge_mode = CAM_EDGE_MODE_FAST; 1816 } else { 1817 edge_application.edge_mode = CAM_EDGE_MODE_OFF; 1818 } 1819 ADD_SET_PARAM_ENTRY_TO_BATCH(pMetaData, CAM_INTF_META_EDGE_MODE, edge_application); 1820 1821 IF_META_AVAILABLE(cam_focus_pos_info_t, cur_pos_info, 1822 CAM_INTF_META_FOCUS_POSITION, pMetaData) { 1823 qcamera_sm_internal_evt_payload_t *payload = 1824 (qcamera_sm_internal_evt_payload_t *)malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 1825 if (NULL != payload) { 1826 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 1827 payload->evt_type = QCAMERA_INTERNAL_EVT_FOCUS_POS_UPDATE; 1828 payload->focus_pos = *cur_pos_info; 1829 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 1830 if (rc != NO_ERROR) { 1831 ALOGE("%s: processEvt focus_pos_update failed", __func__); 1832 free(payload); 1833 payload = NULL; 1834 } 1835 } else { 1836 ALOGE("%s: No memory for focus_pos_update qcamera_sm_internal_evt_payload_t", __func__); 1837 } 1838 } 1839 1840 //Function to upadte metadata for frame based parameter 1841 pme->updateMetadata(pMetaData); 1842 1843 stream->bufDone(frame->buf_idx); 1844 free(super_frame); 1845 1846 CDBG("[KPI Perf] %s : END", __func__); 1847 } 1848 1849 /*=========================================================================== 1850 * FUNCTION : reprocess_stream_cb_routine 1851 * 1852 * DESCRIPTION: helper function to handle reprocess frame from reprocess stream 1853 (after reprocess, e.g., ZSL snapshot frame after WNR if 1854 * WNR is enabled) 1855 * 1856 * PARAMETERS : 1857 * @super_frame : received super buffer 1858 * @stream : stream object 1859 * @userdata : user data ptr 1860 * 1861 * RETURN : None 1862 * 1863 * NOTE : caller passes the ownership of super_frame, it's our 1864 * responsibility to free super_frame once it's done. In this 1865 * case, reprocessed frame need to be passed to postprocessor 1866 * for jpeg encoding. 1867 *==========================================================================*/ 1868 void QCamera2HardwareInterface::reprocess_stream_cb_routine(mm_camera_super_buf_t * super_frame, 1869 QCameraStream * /*stream*/, 1870 void * userdata) 1871 { 1872 ATRACE_CALL(); 1873 CDBG_HIGH("[KPI Perf] %s: E", __func__); 1874 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 1875 if (pme == NULL || 1876 pme->mCameraHandle == NULL || 1877 pme->mCameraHandle->camera_handle != super_frame->camera_handle){ 1878 ALOGE("%s: camera obj not valid", __func__); 1879 // simply free super frame 1880 free(super_frame); 1881 return; 1882 } 1883 1884 pme->m_postprocessor.processPPData(super_frame); 1885 1886 CDBG_HIGH("[KPI Perf] %s: X", __func__); 1887 } 1888 1889 /*=========================================================================== 1890 * FUNCTION : dumpFrameToFile 1891 * 1892 * DESCRIPTION: helper function to dump jpeg into file for debug purpose. 1893 * 1894 * PARAMETERS : 1895 * @data : data ptr 1896 * @size : length of data buffer 1897 * @index : identifier for data 1898 * 1899 * RETURN : None 1900 *==========================================================================*/ 1901 void QCamera2HardwareInterface::dumpJpegToFile(const void *data, 1902 size_t size, uint32_t index) 1903 { 1904 char value[PROPERTY_VALUE_MAX]; 1905 property_get("persist.camera.dumpimg", value, "0"); 1906 uint32_t enabled = (uint32_t) atoi(value); 1907 uint32_t frm_num = 0; 1908 uint32_t skip_mode = 0; 1909 1910 char buf[32]; 1911 cam_dimension_t dim; 1912 memset(buf, 0, sizeof(buf)); 1913 memset(&dim, 0, sizeof(dim)); 1914 1915 if(((enabled & QCAMERA_DUMP_FRM_JPEG) && data) || 1916 ((true == m_bIntJpegEvtPending) && data)) { 1917 frm_num = ((enabled & 0xffff0000) >> 16); 1918 if(frm_num == 0) { 1919 frm_num = 10; //default 10 frames 1920 } 1921 if(frm_num > 256) { 1922 frm_num = 256; //256 buffers cycle around 1923 } 1924 skip_mode = ((enabled & 0x0000ff00) >> 8); 1925 if(skip_mode == 0) { 1926 skip_mode = 1; //no-skip 1927 } 1928 1929 if( mDumpSkipCnt % skip_mode == 0) { 1930 if((frm_num == 256) && (mDumpFrmCnt >= frm_num)) { 1931 // reset frame count if cycling 1932 mDumpFrmCnt = 0; 1933 } 1934 if (mDumpFrmCnt <= frm_num) { 1935 snprintf(buf, sizeof(buf), QCAMERA_DUMP_FRM_LOCATION "%d_%d.jpg", 1936 mDumpFrmCnt, index); 1937 if (true == m_bIntJpegEvtPending) { 1938 strlcpy(m_BackendFileName, buf, sizeof(buf)); 1939 mBackendFileSize = size; 1940 } 1941 1942 int file_fd = open(buf, O_RDWR | O_CREAT, 0777); 1943 if (file_fd > 0) { 1944 ssize_t written_len = write(file_fd, data, size); 1945 fchmod(file_fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 1946 CDBG_HIGH("%s: written number of bytes %zd\n", 1947 __func__, written_len); 1948 close(file_fd); 1949 } else { 1950 ALOGE("%s: fail t open file for image dumping", __func__); 1951 } 1952 if (false == m_bIntJpegEvtPending) { 1953 mDumpFrmCnt++; 1954 } 1955 } 1956 } 1957 mDumpSkipCnt++; 1958 } 1959 } 1960 1961 1962 void QCamera2HardwareInterface::dumpMetadataToFile(QCameraStream *stream, 1963 mm_camera_buf_def_t *frame,char *type) 1964 { 1965 char value[PROPERTY_VALUE_MAX]; 1966 uint32_t frm_num = 0; 1967 metadata_buffer_t *metadata = (metadata_buffer_t *)frame->buffer; 1968 property_get("persist.camera.dumpmetadata", value, "0"); 1969 uint32_t enabled = (uint32_t) atoi(value); 1970 if (stream == NULL) { 1971 CDBG_HIGH("No op"); 1972 return; 1973 } 1974 1975 uint32_t dumpFrmCnt = stream->mDumpMetaFrame; 1976 if(enabled){ 1977 frm_num = ((enabled & 0xffff0000) >> 16); 1978 if (frm_num == 0) { 1979 frm_num = 10; //default 10 frames 1980 } 1981 if (frm_num > 256) { 1982 frm_num = 256; //256 buffers cycle around 1983 } 1984 if ((frm_num == 256) && (dumpFrmCnt >= frm_num)) { 1985 // reset frame count if cycling 1986 dumpFrmCnt = 0; 1987 } 1988 CDBG_HIGH("dumpFrmCnt= %u, frm_num = %u", dumpFrmCnt, frm_num); 1989 if (dumpFrmCnt < frm_num) { 1990 char timeBuf[128]; 1991 char buf[32]; 1992 memset(buf, 0, sizeof(buf)); 1993 memset(timeBuf, 0, sizeof(timeBuf)); 1994 time_t current_time; 1995 struct tm * timeinfo; 1996 time (¤t_time); 1997 timeinfo = localtime (¤t_time); 1998 if (NULL != timeinfo) { 1999 strftime(timeBuf, sizeof(timeBuf), 2000 QCAMERA_DUMP_FRM_LOCATION "%Y%m%d%H%M%S", timeinfo); 2001 } 2002 String8 filePath(timeBuf); 2003 snprintf(buf, sizeof(buf), "%um_%s_%d.bin", dumpFrmCnt, type, frame->frame_idx); 2004 filePath.append(buf); 2005 int file_fd = open(filePath.string(), O_RDWR | O_CREAT, 0777); 2006 if (file_fd > 0) { 2007 ssize_t written_len = 0; 2008 metadata->tuning_params.tuning_data_version = TUNING_DATA_VERSION; 2009 void *data = (void *)((uint8_t *)&metadata->tuning_params.tuning_data_version); 2010 written_len += write(file_fd, data, sizeof(uint32_t)); 2011 data = (void *)((uint8_t *)&metadata->tuning_params.tuning_sensor_data_size); 2012 CDBG_HIGH("tuning_sensor_data_size %d",(int)(*(int *)data)); 2013 written_len += write(file_fd, data, sizeof(uint32_t)); 2014 data = (void *)((uint8_t *)&metadata->tuning_params.tuning_vfe_data_size); 2015 CDBG_HIGH("tuning_vfe_data_size %d",(int)(*(int *)data)); 2016 written_len += write(file_fd, data, sizeof(uint32_t)); 2017 data = (void *)((uint8_t *)&metadata->tuning_params.tuning_cpp_data_size); 2018 CDBG_HIGH("tuning_cpp_data_size %d",(int)(*(int *)data)); 2019 written_len += write(file_fd, data, sizeof(uint32_t)); 2020 data = (void *)((uint8_t *)&metadata->tuning_params.tuning_cac_data_size); 2021 CDBG_HIGH("tuning_cac_data_size %d",(int)(*(int *)data)); 2022 written_len += write(file_fd, data, sizeof(uint32_t)); 2023 data = (void *)((uint8_t *)&metadata->tuning_params.tuning_cac_data_size2); 2024 CDBG_HIGH("%s < skrajago >tuning_cac_data_size %d",__func__,(int)(*(int *)data)); 2025 written_len += write(file_fd, data, sizeof(uint32_t)); 2026 size_t total_size = metadata->tuning_params.tuning_sensor_data_size; 2027 data = (void *)((uint8_t *)&metadata->tuning_params.data); 2028 written_len += write(file_fd, data, total_size); 2029 total_size = metadata->tuning_params.tuning_vfe_data_size; 2030 data = (void *)((uint8_t *)&metadata->tuning_params.data[TUNING_VFE_DATA_OFFSET]); 2031 written_len += write(file_fd, data, total_size); 2032 total_size = metadata->tuning_params.tuning_cpp_data_size; 2033 data = (void *)((uint8_t *)&metadata->tuning_params.data[TUNING_CPP_DATA_OFFSET]); 2034 written_len += write(file_fd, data, total_size); 2035 total_size = metadata->tuning_params.tuning_cac_data_size; 2036 data = (void *)((uint8_t *)&metadata->tuning_params.data[TUNING_CAC_DATA_OFFSET]); 2037 written_len += write(file_fd, data, total_size); 2038 close(file_fd); 2039 }else { 2040 ALOGE("%s: fail t open file for image dumping", __func__); 2041 } 2042 dumpFrmCnt++; 2043 } 2044 } 2045 stream->mDumpMetaFrame = dumpFrmCnt; 2046 } 2047 /*=========================================================================== 2048 * FUNCTION : dumpFrameToFile 2049 * 2050 * DESCRIPTION: helper function to dump frame into file for debug purpose. 2051 * 2052 * PARAMETERS : 2053 * @data : data ptr 2054 * @size : length of data buffer 2055 * @index : identifier for data 2056 * @dump_type : type of the frame to be dumped. Only such 2057 * dump type is enabled, the frame will be 2058 * dumped into a file. 2059 * 2060 * RETURN : None 2061 *==========================================================================*/ 2062 void QCamera2HardwareInterface::dumpFrameToFile(QCameraStream *stream, 2063 mm_camera_buf_def_t *frame, uint32_t dump_type) 2064 { 2065 char value[PROPERTY_VALUE_MAX]; 2066 property_get("persist.camera.dumpimg", value, "0"); 2067 uint32_t enabled = (uint32_t) atoi(value); 2068 uint32_t frm_num = 0; 2069 uint32_t skip_mode = 0; 2070 2071 if (NULL == stream) { 2072 ALOGE("%s stream object is null", __func__); 2073 return; 2074 } 2075 2076 uint32_t dumpFrmCnt = stream->mDumpFrame; 2077 2078 if (true == m_bIntRawEvtPending) { 2079 enabled = QCAMERA_DUMP_FRM_RAW; 2080 } 2081 2082 if((enabled & QCAMERA_DUMP_FRM_MASK_ALL)) { 2083 if((enabled & dump_type) && stream && frame) { 2084 frm_num = ((enabled & 0xffff0000) >> 16); 2085 if(frm_num == 0) { 2086 frm_num = 10; //default 10 frames 2087 } 2088 if(frm_num > 256) { 2089 frm_num = 256; //256 buffers cycle around 2090 } 2091 skip_mode = ((enabled & 0x0000ff00) >> 8); 2092 if(skip_mode == 0) { 2093 skip_mode = 1; //no-skip 2094 } 2095 if(stream->mDumpSkipCnt == 0) 2096 stream->mDumpSkipCnt = 1; 2097 2098 if( stream->mDumpSkipCnt % skip_mode == 0) { 2099 if((frm_num == 256) && (dumpFrmCnt >= frm_num)) { 2100 // reset frame count if cycling 2101 dumpFrmCnt = 0; 2102 } 2103 if (dumpFrmCnt <= frm_num) { 2104 char buf[32]; 2105 char timeBuf[128]; 2106 time_t current_time; 2107 struct tm * timeinfo; 2108 2109 memset(timeBuf, 0, sizeof(timeBuf)); 2110 2111 time (¤t_time); 2112 timeinfo = localtime (¤t_time); 2113 memset(buf, 0, sizeof(buf)); 2114 2115 cam_dimension_t dim; 2116 memset(&dim, 0, sizeof(dim)); 2117 stream->getFrameDimension(dim); 2118 2119 cam_frame_len_offset_t offset; 2120 memset(&offset, 0, sizeof(cam_frame_len_offset_t)); 2121 stream->getFrameOffset(offset); 2122 2123 if (NULL != timeinfo) { 2124 strftime(timeBuf, sizeof(timeBuf), 2125 QCAMERA_DUMP_FRM_LOCATION "%Y%m%d%H%M%S", timeinfo); 2126 } 2127 String8 filePath(timeBuf); 2128 switch (dump_type) { 2129 case QCAMERA_DUMP_FRM_PREVIEW: 2130 { 2131 snprintf(buf, sizeof(buf), "%dp_%dx%d_%d.yuv", 2132 dumpFrmCnt, dim.width, dim.height, frame->frame_idx); 2133 } 2134 break; 2135 case QCAMERA_DUMP_FRM_THUMBNAIL: 2136 { 2137 snprintf(buf, sizeof(buf), "%dt_%dx%d_%d.yuv", 2138 dumpFrmCnt, dim.width, dim.height, frame->frame_idx); 2139 } 2140 break; 2141 case QCAMERA_DUMP_FRM_SNAPSHOT: 2142 { 2143 mParameters.getStreamDimension(CAM_STREAM_TYPE_SNAPSHOT, dim); 2144 snprintf(buf, sizeof(buf), "%ds_%dx%d_%d.yuv", 2145 dumpFrmCnt, dim.width, dim.height, frame->frame_idx); 2146 } 2147 break; 2148 case QCAMERA_DUMP_FRM_VIDEO: 2149 { 2150 snprintf(buf, sizeof(buf), "%dv_%dx%d_%d.yuv", 2151 dumpFrmCnt, dim.width, dim.height, frame->frame_idx); 2152 } 2153 break; 2154 case QCAMERA_DUMP_FRM_RAW: 2155 { 2156 mParameters.getStreamDimension(CAM_STREAM_TYPE_RAW, dim); 2157 snprintf(buf, sizeof(buf), "%dr_%dx%d_%d.raw", 2158 dumpFrmCnt, dim.width, dim.height, frame->frame_idx); 2159 } 2160 break; 2161 case QCAMERA_DUMP_FRM_JPEG: 2162 { 2163 mParameters.getStreamDimension(CAM_STREAM_TYPE_SNAPSHOT, dim); 2164 snprintf(buf, sizeof(buf), "%dj_%dx%d_%d.yuv", 2165 dumpFrmCnt, dim.width, dim.height, frame->frame_idx); 2166 } 2167 break; 2168 default: 2169 ALOGE("%s: Not supported for dumping stream type %d", 2170 __func__, dump_type); 2171 return; 2172 } 2173 2174 filePath.append(buf); 2175 int file_fd = open(filePath.string(), O_RDWR | O_CREAT, 0777); 2176 ssize_t written_len = 0; 2177 if (file_fd > 0) { 2178 void *data = NULL; 2179 2180 fchmod(file_fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 2181 for (uint32_t i = 0; i < offset.num_planes; i++) { 2182 uint32_t index = offset.mp[i].offset; 2183 if (i > 0) { 2184 index += offset.mp[i-1].len; 2185 } 2186 for (int j = 0; j < offset.mp[i].height; j++) { 2187 data = (void *)((uint8_t *)frame->buffer + index); 2188 written_len += write(file_fd, data, 2189 (size_t)offset.mp[i].width); 2190 index += (uint32_t)offset.mp[i].stride; 2191 } 2192 } 2193 2194 CDBG_HIGH("%s: written number of bytes %ld\n", 2195 __func__, written_len); 2196 close(file_fd); 2197 } else { 2198 ALOGE("%s: fail t open file for image dumping", __func__); 2199 } 2200 if (true == m_bIntRawEvtPending) { 2201 strlcpy(m_BackendFileName, filePath.string(), QCAMERA_MAX_FILEPATH_LENGTH); 2202 mBackendFileSize = (size_t)written_len; 2203 } else { 2204 dumpFrmCnt++; 2205 } 2206 } 2207 } 2208 stream->mDumpSkipCnt++; 2209 } 2210 } else { 2211 dumpFrmCnt = 0; 2212 } 2213 stream->mDumpFrame = dumpFrmCnt; 2214 } 2215 2216 /*=========================================================================== 2217 * FUNCTION : debugShowVideoFPS 2218 * 2219 * DESCRIPTION: helper function to log video frame FPS for debug purpose. 2220 * 2221 * PARAMETERS : None 2222 * 2223 * RETURN : None 2224 *==========================================================================*/ 2225 void QCamera2HardwareInterface::debugShowVideoFPS() 2226 { 2227 mVFrameCount++; 2228 nsecs_t now = systemTime(); 2229 nsecs_t diff = now - mVLastFpsTime; 2230 if (diff > ms2ns(250)) { 2231 mVFps = (((double)(mVFrameCount - mVLastFrameCount)) * 2232 (double)(s2ns(1))) / (double)diff; 2233 CDBG_HIGH("Video Frames Per Second: %.4f Cam ID = %d", mVFps, mCameraId); 2234 mVLastFpsTime = now; 2235 mVLastFrameCount = mVFrameCount; 2236 } 2237 } 2238 2239 /*=========================================================================== 2240 * FUNCTION : debugShowPreviewFPS 2241 * 2242 * DESCRIPTION: helper function to log preview frame FPS for debug purpose. 2243 * 2244 * PARAMETERS : None 2245 * 2246 * RETURN : None 2247 *==========================================================================*/ 2248 void QCamera2HardwareInterface::debugShowPreviewFPS() 2249 { 2250 mPFrameCount++; 2251 nsecs_t now = systemTime(); 2252 nsecs_t diff = now - mPLastFpsTime; 2253 if (diff > ms2ns(250)) { 2254 mPFps = (((double)(mPFrameCount - mPLastFrameCount)) * 2255 (double)(s2ns(1))) / (double)diff; 2256 CDBG_HIGH("[KPI Perf] %s: PROFILE_PREVIEW_FRAMES_PER_SECOND : %.4f Cam ID = %d", 2257 __func__, mPFps, mCameraId); 2258 mPLastFpsTime = now; 2259 mPLastFrameCount = mPFrameCount; 2260 } 2261 } 2262 2263 /*=========================================================================== 2264 * FUNCTION : ~QCameraCbNotifier 2265 * 2266 * DESCRIPTION: Destructor for exiting the callback context. 2267 * 2268 * PARAMETERS : None 2269 * 2270 * RETURN : None 2271 *==========================================================================*/ 2272 QCameraCbNotifier::~QCameraCbNotifier() 2273 { 2274 } 2275 2276 /*=========================================================================== 2277 * FUNCTION : exit 2278 * 2279 * DESCRIPTION: exit notify thread. 2280 * 2281 * PARAMETERS : None 2282 * 2283 * RETURN : None 2284 *==========================================================================*/ 2285 void QCameraCbNotifier::exit() 2286 { 2287 mActive = false; 2288 mProcTh.exit(); 2289 } 2290 2291 /*=========================================================================== 2292 * FUNCTION : releaseNotifications 2293 * 2294 * DESCRIPTION: callback for releasing data stored in the callback queue. 2295 * 2296 * PARAMETERS : 2297 * @data : data to be released 2298 * @user_data : context data 2299 * 2300 * RETURN : None 2301 *==========================================================================*/ 2302 void QCameraCbNotifier::releaseNotifications(void *data, void *user_data) 2303 { 2304 qcamera_callback_argm_t *arg = ( qcamera_callback_argm_t * ) data; 2305 2306 if ( ( NULL != arg ) && ( NULL != user_data ) ) { 2307 if ( arg->release_cb ) { 2308 arg->release_cb(arg->user_data, arg->cookie, FAILED_TRANSACTION); 2309 } 2310 } 2311 } 2312 2313 /*=========================================================================== 2314 * FUNCTION : matchSnapshotNotifications 2315 * 2316 * DESCRIPTION: matches snapshot data callbacks 2317 * 2318 * PARAMETERS : 2319 * @data : data to match 2320 * @user_data : context data 2321 * 2322 * RETURN : bool match 2323 * true - match found 2324 * false- match not found 2325 *==========================================================================*/ 2326 bool QCameraCbNotifier::matchSnapshotNotifications(void *data, 2327 void */*user_data*/) 2328 { 2329 qcamera_callback_argm_t *arg = ( qcamera_callback_argm_t * ) data; 2330 if ( NULL != arg ) { 2331 if ( QCAMERA_DATA_SNAPSHOT_CALLBACK == arg->cb_type ) { 2332 return true; 2333 } 2334 } 2335 2336 return false; 2337 } 2338 2339 /*=========================================================================== 2340 * FUNCTION : matchPreviewNotifications 2341 * 2342 * DESCRIPTION: matches preview data callbacks 2343 * 2344 * PARAMETERS : 2345 * @data : data to match 2346 * @user_data : context data 2347 * 2348 * RETURN : bool match 2349 * true - match found 2350 * false- match not found 2351 *==========================================================================*/ 2352 bool QCameraCbNotifier::matchPreviewNotifications(void *data, 2353 void */*user_data*/) 2354 { 2355 qcamera_callback_argm_t *arg = ( qcamera_callback_argm_t * ) data; 2356 if (NULL != arg) { 2357 if ((QCAMERA_DATA_CALLBACK == arg->cb_type) && 2358 (CAMERA_MSG_PREVIEW_FRAME == arg->msg_type)) { 2359 return true; 2360 } 2361 } 2362 2363 return false; 2364 } 2365 2366 /*=========================================================================== 2367 * FUNCTION : cbNotifyRoutine 2368 * 2369 * DESCRIPTION: callback thread which interfaces with the upper layers 2370 * given input commands. 2371 * 2372 * PARAMETERS : 2373 * @data : context data 2374 * 2375 * RETURN : None 2376 *==========================================================================*/ 2377 void * QCameraCbNotifier::cbNotifyRoutine(void * data) 2378 { 2379 int running = 1; 2380 int ret; 2381 QCameraCbNotifier *pme = (QCameraCbNotifier *)data; 2382 QCameraCmdThread *cmdThread = &pme->mProcTh; 2383 cmdThread->setName("CAM_cbNotify"); 2384 uint8_t isSnapshotActive = FALSE; 2385 bool longShotEnabled = false; 2386 uint32_t numOfSnapshotExpected = 0; 2387 uint32_t numOfSnapshotRcvd = 0; 2388 int32_t cbStatus = NO_ERROR; 2389 2390 CDBG("%s: E", __func__); 2391 do { 2392 do { 2393 ret = cam_sem_wait(&cmdThread->cmd_sem); 2394 if (ret != 0 && errno != EINVAL) { 2395 CDBG("%s: cam_sem_wait error (%s)", 2396 __func__, strerror(errno)); 2397 return NULL; 2398 } 2399 } while (ret != 0); 2400 2401 camera_cmd_type_t cmd = cmdThread->getCmd(); 2402 CDBG("%s: get cmd %d", __func__, cmd); 2403 switch (cmd) { 2404 case CAMERA_CMD_TYPE_START_DATA_PROC: 2405 { 2406 isSnapshotActive = TRUE; 2407 numOfSnapshotExpected = pme->mParent->numOfSnapshotsExpected(); 2408 longShotEnabled = pme->mParent->isLongshotEnabled(); 2409 ALOGI("%s: Num Snapshots Expected = %d", 2410 __func__, numOfSnapshotExpected); 2411 numOfSnapshotRcvd = 0; 2412 } 2413 break; 2414 case CAMERA_CMD_TYPE_STOP_DATA_PROC: 2415 { 2416 pme->mDataQ.flushNodes(matchSnapshotNotifications); 2417 isSnapshotActive = FALSE; 2418 2419 numOfSnapshotExpected = 0; 2420 numOfSnapshotRcvd = 0; 2421 } 2422 break; 2423 case CAMERA_CMD_TYPE_DO_NEXT_JOB: 2424 { 2425 qcamera_callback_argm_t *cb = 2426 (qcamera_callback_argm_t *)pme->mDataQ.dequeue(); 2427 cbStatus = NO_ERROR; 2428 if (NULL != cb) { 2429 CDBG("%s: cb type %d received", 2430 __func__, 2431 cb->cb_type); 2432 2433 if (pme->mParent->msgTypeEnabledWithLock(cb->msg_type)) { 2434 switch (cb->cb_type) { 2435 case QCAMERA_NOTIFY_CALLBACK: 2436 { 2437 if (cb->msg_type == CAMERA_MSG_FOCUS) { 2438 ATRACE_INT("Camera:AutoFocus", 0); 2439 CDBG_HIGH("[KPI Perf] %s : PROFILE_SENDING_FOCUS_EVT_TO APP", 2440 __func__); 2441 } 2442 if (pme->mNotifyCb) { 2443 pme->mNotifyCb(cb->msg_type, 2444 cb->ext1, 2445 cb->ext2, 2446 pme->mCallbackCookie); 2447 } else { 2448 ALOGE("%s : notify callback not set!", 2449 __func__); 2450 } 2451 } 2452 break; 2453 case QCAMERA_DATA_CALLBACK: 2454 { 2455 if (pme->mDataCb) { 2456 pme->mDataCb(cb->msg_type, 2457 cb->data, 2458 cb->index, 2459 cb->metadata, 2460 pme->mCallbackCookie); 2461 } else { 2462 ALOGE("%s : data callback not set!", 2463 __func__); 2464 } 2465 } 2466 break; 2467 case QCAMERA_DATA_TIMESTAMP_CALLBACK: 2468 { 2469 if(pme->mDataCbTimestamp) { 2470 pme->mDataCbTimestamp(cb->timestamp, 2471 cb->msg_type, 2472 cb->data, 2473 cb->index, 2474 pme->mCallbackCookie); 2475 } else { 2476 ALOGE("%s:data cb with tmp not set!", 2477 __func__); 2478 } 2479 } 2480 break; 2481 case QCAMERA_DATA_SNAPSHOT_CALLBACK: 2482 { 2483 if (TRUE == isSnapshotActive && pme->mDataCb ) { 2484 if (!longShotEnabled) { 2485 numOfSnapshotRcvd++; 2486 ALOGI("%s: [ZSL Retro] Num Snapshots Received = %d", __func__, 2487 numOfSnapshotRcvd); 2488 if (numOfSnapshotExpected > 0 && 2489 (numOfSnapshotExpected == numOfSnapshotRcvd)) { 2490 ALOGI("%s: [ZSL Retro] Expected snapshot received = %d", 2491 __func__, numOfSnapshotRcvd); 2492 // notify HWI that snapshot is done 2493 pme->mParent->processSyncEvt(QCAMERA_SM_EVT_SNAPSHOT_DONE, 2494 NULL); 2495 } 2496 } 2497 pme->mDataCb(cb->msg_type, 2498 cb->data, 2499 cb->index, 2500 cb->metadata, 2501 pme->mCallbackCookie); 2502 } 2503 } 2504 break; 2505 default: 2506 { 2507 ALOGE("%s : invalid cb type %d", 2508 __func__, 2509 cb->cb_type); 2510 cbStatus = BAD_VALUE; 2511 } 2512 break; 2513 }; 2514 } else { 2515 ALOGE("%s : cb message type %d not enabled!", 2516 __func__, 2517 cb->msg_type); 2518 cbStatus = INVALID_OPERATION; 2519 } 2520 if ( cb->release_cb ) { 2521 cb->release_cb(cb->user_data, cb->cookie, cbStatus); 2522 } 2523 delete cb; 2524 } else { 2525 ALOGE("%s: invalid cb type passed", __func__); 2526 } 2527 } 2528 break; 2529 case CAMERA_CMD_TYPE_EXIT: 2530 { 2531 running = 0; 2532 pme->mDataQ.flush(); 2533 } 2534 break; 2535 default: 2536 break; 2537 } 2538 } while (running); 2539 CDBG("%s: X", __func__); 2540 2541 return NULL; 2542 } 2543 2544 /*=========================================================================== 2545 * FUNCTION : notifyCallback 2546 * 2547 * DESCRIPTION: Enqueus pending callback notifications for the upper layers. 2548 * 2549 * PARAMETERS : 2550 * @cbArgs : callback arguments 2551 * 2552 * RETURN : int32_t type of status 2553 * NO_ERROR -- success 2554 * none-zero failure code 2555 *==========================================================================*/ 2556 int32_t QCameraCbNotifier::notifyCallback(qcamera_callback_argm_t &cbArgs) 2557 { 2558 if (!mActive) { 2559 ALOGE("%s: notify thread is not active", __func__); 2560 return UNKNOWN_ERROR; 2561 } 2562 2563 qcamera_callback_argm_t *cbArg = new qcamera_callback_argm_t(); 2564 if (NULL == cbArg) { 2565 ALOGE("%s: no mem for qcamera_callback_argm_t", __func__); 2566 return NO_MEMORY; 2567 } 2568 memset(cbArg, 0, sizeof(qcamera_callback_argm_t)); 2569 *cbArg = cbArgs; 2570 2571 if (mDataQ.enqueue((void *)cbArg)) { 2572 return mProcTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE); 2573 } else { 2574 ALOGE("%s: Error adding cb data into queue", __func__); 2575 delete cbArg; 2576 return UNKNOWN_ERROR; 2577 } 2578 } 2579 2580 /*=========================================================================== 2581 * FUNCTION : setCallbacks 2582 * 2583 * DESCRIPTION: Initializes the callback functions, which would be used for 2584 * communication with the upper layers and launches the callback 2585 * context in which the callbacks will occur. 2586 * 2587 * PARAMETERS : 2588 * @notifyCb : notification callback 2589 * @dataCb : data callback 2590 * @dataCbTimestamp : data with timestamp callback 2591 * @callbackCookie : callback context data 2592 * 2593 * RETURN : None 2594 *==========================================================================*/ 2595 void QCameraCbNotifier::setCallbacks(camera_notify_callback notifyCb, 2596 camera_data_callback dataCb, 2597 camera_data_timestamp_callback dataCbTimestamp, 2598 void *callbackCookie) 2599 { 2600 if ( ( NULL == mNotifyCb ) && 2601 ( NULL == mDataCb ) && 2602 ( NULL == mDataCbTimestamp ) && 2603 ( NULL == mCallbackCookie ) ) { 2604 mNotifyCb = notifyCb; 2605 mDataCb = dataCb; 2606 mDataCbTimestamp = dataCbTimestamp; 2607 mCallbackCookie = callbackCookie; 2608 mActive = true; 2609 mProcTh.launch(cbNotifyRoutine, this); 2610 } else { 2611 ALOGE("%s : Camera callback notifier already initialized!", 2612 __func__); 2613 } 2614 } 2615 2616 /*=========================================================================== 2617 * FUNCTION : flushPreviewNotifications 2618 * 2619 * DESCRIPTION: flush all pending preview notifications 2620 * from the notifier queue 2621 * 2622 * PARAMETERS : None 2623 * 2624 * RETURN : int32_t type of status 2625 * NO_ERROR -- success 2626 * none-zero failure code 2627 *==========================================================================*/ 2628 int32_t QCameraCbNotifier::flushPreviewNotifications() 2629 { 2630 if (!mActive) { 2631 ALOGE("%s: notify thread is not active", __func__); 2632 return UNKNOWN_ERROR; 2633 } 2634 2635 mDataQ.flushNodes(matchPreviewNotifications); 2636 2637 return NO_ERROR; 2638 } 2639 2640 /*=========================================================================== 2641 * FUNCTION : startSnapshots 2642 * 2643 * DESCRIPTION: Enables snapshot mode 2644 * 2645 * PARAMETERS : None 2646 * 2647 * RETURN : int32_t type of status 2648 * NO_ERROR -- success 2649 * none-zero failure code 2650 *==========================================================================*/ 2651 int32_t QCameraCbNotifier::startSnapshots() 2652 { 2653 return mProcTh.sendCmd(CAMERA_CMD_TYPE_START_DATA_PROC, FALSE, TRUE); 2654 } 2655 2656 /*=========================================================================== 2657 * FUNCTION : stopSnapshots 2658 * 2659 * DESCRIPTION: Disables snapshot processing mode 2660 * 2661 * PARAMETERS : None 2662 * 2663 * RETURN : None 2664 *==========================================================================*/ 2665 void QCameraCbNotifier::stopSnapshots() 2666 { 2667 mProcTh.sendCmd(CAMERA_CMD_TYPE_STOP_DATA_PROC, FALSE, TRUE); 2668 } 2669 2670 }; // namespace qcamera 2671