1 /* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. 2 * 3 * Redistribution and use in source and binary forms, with or without 4 * modification, are permitted provided that the following conditions are 5 * met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above 9 * copyright notice, this list of conditions and the following 10 * disclaimer in the documentation and/or other materials provided 11 * with the distribution. 12 * * Neither the name of The Linux Foundation nor the names of its 13 * contributors may be used to endorse or promote products derived 14 * from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 */ 29 30 #define LOG_TAG "QCamera2HWI" 31 32 // System dependencies 33 #include <fcntl.h> 34 #include <stdio.h> 35 #include <stdlib.h> 36 #define STAT_H <SYSTEM_HEADER_PREFIX/stat.h> 37 #include STAT_H 38 #include <utils/Errors.h> 39 40 // Camera dependencies 41 #include "QCamera2HWI.h" 42 #include "QCameraTrace.h" 43 44 extern "C" { 45 #include "mm_camera_dbg.h" 46 } 47 48 namespace qcamera { 49 50 /*=========================================================================== 51 * FUNCTION : zsl_channel_cb 52 * 53 * DESCRIPTION: helper function to handle ZSL superbuf callback directly from 54 * mm-camera-interface 55 * 56 * PARAMETERS : 57 * @recvd_frame : received super buffer 58 * @userdata : user data ptr 59 * 60 * RETURN : None 61 * 62 * NOTE : recvd_frame will be released after this call by caller, so if 63 * async operation needed for recvd_frame, it's our responsibility 64 * to save a copy for this variable to be used later. 65 *==========================================================================*/ 66 void QCamera2HardwareInterface::zsl_channel_cb(mm_camera_super_buf_t *recvd_frame, 67 void *userdata) 68 { 69 ATRACE_CALL(); 70 LOGH("[KPI Perf]: E"); 71 char value[PROPERTY_VALUE_MAX]; 72 bool dump_raw = false; 73 bool log_matching = false; 74 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 75 if (pme == NULL || 76 pme->mCameraHandle == NULL || 77 pme->mCameraHandle->camera_handle != recvd_frame->camera_handle){ 78 LOGE("camera obj not valid"); 79 return; 80 } 81 82 QCameraChannel *pChannel = pme->m_channels[QCAMERA_CH_TYPE_ZSL]; 83 if (pChannel == NULL || 84 pChannel->getMyHandle() != recvd_frame->ch_id) { 85 LOGE("ZSL channel doesn't exist, return here"); 86 return; 87 } 88 89 if(pme->mParameters.isSceneSelectionEnabled() && 90 !pme->m_stateMachine.isCaptureRunning()) { 91 pme->selectScene(pChannel, recvd_frame); 92 pChannel->bufDone(recvd_frame); 93 return; 94 } 95 96 LOGD("Frame CB Unlock : %d, is AEC Locked: %d", 97 recvd_frame->bUnlockAEC, pme->m_bLedAfAecLock); 98 if(recvd_frame->bUnlockAEC && pme->m_bLedAfAecLock) { 99 qcamera_sm_internal_evt_payload_t *payload = 100 (qcamera_sm_internal_evt_payload_t *)malloc( 101 sizeof(qcamera_sm_internal_evt_payload_t)); 102 if (NULL != payload) { 103 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 104 payload->evt_type = QCAMERA_INTERNAL_EVT_RETRO_AEC_UNLOCK; 105 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 106 if (rc != NO_ERROR) { 107 LOGE("processEvt for retro AEC unlock failed"); 108 free(payload); 109 payload = NULL; 110 } 111 } else { 112 LOGE("No memory for retro AEC event"); 113 } 114 } 115 116 // Check if retro-active frames are completed and camera is 117 // ready to go ahead with LED estimation for regular frames 118 if (recvd_frame->bReadyForPrepareSnapshot) { 119 // Send an event 120 LOGD("Ready for Prepare Snapshot, signal "); 121 qcamera_sm_internal_evt_payload_t *payload = 122 (qcamera_sm_internal_evt_payload_t *)malloc( 123 sizeof(qcamera_sm_internal_evt_payload_t)); 124 if (NULL != payload) { 125 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 126 payload->evt_type = QCAMERA_INTERNAL_EVT_READY_FOR_SNAPSHOT; 127 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 128 if (rc != NO_ERROR) { 129 LOGW("processEvt Ready for Snaphot failed"); 130 free(payload); 131 payload = NULL; 132 } 133 } else { 134 LOGE("No memory for prepare signal event detect" 135 " qcamera_sm_internal_evt_payload_t"); 136 } 137 } 138 139 /* indicate the parent that capture is done */ 140 pme->captureDone(); 141 142 // save a copy for the superbuf 143 mm_camera_super_buf_t* frame = 144 (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t)); 145 if (frame == NULL) { 146 LOGE("Error allocating memory to save received_frame structure."); 147 pChannel->bufDone(recvd_frame); 148 return; 149 } 150 *frame = *recvd_frame; 151 152 if (recvd_frame->num_bufs > 0) { 153 LOGI("[KPI Perf]: superbuf frame_idx %d", 154 recvd_frame->bufs[0]->frame_idx); 155 } 156 157 // DUMP RAW if available 158 property_get("persist.camera.zsl_raw", value, "0"); 159 dump_raw = atoi(value) > 0 ? true : false; 160 if (dump_raw) { 161 for (uint32_t i = 0; i < recvd_frame->num_bufs; i++) { 162 if (recvd_frame->bufs[i]->stream_type == CAM_STREAM_TYPE_RAW) { 163 mm_camera_buf_def_t * raw_frame = recvd_frame->bufs[i]; 164 QCameraStream *pStream = pChannel->getStreamByHandle(raw_frame->stream_id); 165 if (NULL != pStream) { 166 pme->dumpFrameToFile(pStream, raw_frame, QCAMERA_DUMP_FRM_RAW); 167 } 168 break; 169 } 170 } 171 } 172 173 for (uint32_t i = 0; i < recvd_frame->num_bufs; i++) { 174 if (recvd_frame->bufs[i]->stream_type == CAM_STREAM_TYPE_SNAPSHOT) { 175 mm_camera_buf_def_t * yuv_frame = recvd_frame->bufs[i]; 176 QCameraStream *pStream = pChannel->getStreamByHandle(yuv_frame->stream_id); 177 if (NULL != pStream) { 178 pme->dumpFrameToFile(pStream, yuv_frame, QCAMERA_DUMP_FRM_INPUT_REPROCESS); 179 } 180 break; 181 } 182 } 183 // 184 // whether need FD Metadata along with Snapshot frame in ZSL mode 185 if(pme->needFDMetadata(QCAMERA_CH_TYPE_ZSL)){ 186 //Need Face Detection result for snapshot frames 187 //Get the Meta Data frames 188 mm_camera_buf_def_t *pMetaFrame = NULL; 189 for (uint32_t i = 0; i < frame->num_bufs; i++) { 190 QCameraStream *pStream = pChannel->getStreamByHandle(frame->bufs[i]->stream_id); 191 if (pStream != NULL) { 192 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) { 193 pMetaFrame = frame->bufs[i]; //find the metadata 194 break; 195 } 196 } 197 } 198 199 if(pMetaFrame != NULL){ 200 metadata_buffer_t *pMetaData = (metadata_buffer_t *)pMetaFrame->buffer; 201 //send the face detection info 202 cam_faces_data_t faces_data; 203 pme->fillFacesData(faces_data, pMetaData); 204 //HARD CODE here before MCT can support 205 faces_data.detection_data.fd_type = QCAMERA_FD_SNAPSHOT; 206 207 qcamera_sm_internal_evt_payload_t *payload = 208 (qcamera_sm_internal_evt_payload_t *)malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 209 if (NULL != payload) { 210 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 211 payload->evt_type = QCAMERA_INTERNAL_EVT_FACE_DETECT_RESULT; 212 payload->faces_data = faces_data; 213 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 214 if (rc != NO_ERROR) { 215 LOGW("processEvt face_detection_result failed"); 216 free(payload); 217 payload = NULL; 218 } 219 } else { 220 LOGE("No memory for face_detection_result qcamera_sm_internal_evt_payload_t"); 221 } 222 } 223 } 224 225 property_get("persist.camera.dumpmetadata", value, "0"); 226 int32_t enabled = atoi(value); 227 if (enabled) { 228 mm_camera_buf_def_t *pMetaFrame = NULL; 229 QCameraStream *pStream = NULL; 230 for (uint32_t i = 0; i < frame->num_bufs; i++) { 231 pStream = pChannel->getStreamByHandle(frame->bufs[i]->stream_id); 232 if (pStream != NULL) { 233 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) { 234 pMetaFrame = frame->bufs[i]; 235 if (pMetaFrame != NULL && 236 ((metadata_buffer_t *)pMetaFrame->buffer)->is_tuning_params_valid) { 237 pme->dumpMetadataToFile(pStream, pMetaFrame, (char *) "ZSL_Snapshot"); 238 } 239 break; 240 } 241 } 242 } 243 } 244 245 property_get("persist.camera.zsl_matching", value, "0"); 246 log_matching = atoi(value) > 0 ? true : false; 247 if (log_matching) { 248 LOGH("ZSL super buffer contains:"); 249 QCameraStream *pStream = NULL; 250 for (uint32_t i = 0; i < frame->num_bufs; i++) { 251 pStream = pChannel->getStreamByHandle(frame->bufs[i]->stream_id); 252 if (pStream != NULL ) { 253 LOGH("Buffer with V4L index %d frame index %d of type %d Timestamp: %ld %ld ", 254 frame->bufs[i]->buf_idx, 255 frame->bufs[i]->frame_idx, 256 pStream->getMyType(), 257 frame->bufs[i]->ts.tv_sec, 258 frame->bufs[i]->ts.tv_nsec); 259 } 260 } 261 } 262 263 // Wait on Postproc initialization if needed 264 // then send to postprocessor 265 if ((NO_ERROR != pme->waitDeferredWork(pme->mReprocJob)) || 266 (NO_ERROR != pme->m_postprocessor.processData(frame))) { 267 LOGE("Failed to trigger process data"); 268 pChannel->bufDone(recvd_frame); 269 free(frame); 270 frame = NULL; 271 return; 272 } 273 274 LOGH("[KPI Perf]: X"); 275 } 276 277 /*=========================================================================== 278 * FUNCTION : selectScene 279 * 280 * DESCRIPTION: send a preview callback when a specific selected scene is applied 281 * 282 * PARAMETERS : 283 * @pChannel: Camera channel 284 * @frame : Bundled super buffer 285 * 286 * RETURN : int32_t type of status 287 * NO_ERROR -- success 288 * none-zero failure code 289 *==========================================================================*/ 290 int32_t QCamera2HardwareInterface::selectScene(QCameraChannel *pChannel, 291 mm_camera_super_buf_t *frame) 292 { 293 mm_camera_buf_def_t *pMetaFrame = NULL; 294 QCameraStream *pStream = NULL; 295 int32_t rc = NO_ERROR; 296 297 if ((NULL == frame) || (NULL == pChannel)) { 298 LOGE("Invalid scene select input"); 299 return BAD_VALUE; 300 } 301 302 cam_scene_mode_type selectedScene = mParameters.getSelectedScene(); 303 if (CAM_SCENE_MODE_MAX == selectedScene) { 304 LOGL("No selected scene"); 305 return NO_ERROR; 306 } 307 308 for (uint32_t i = 0; i < frame->num_bufs; i++) { 309 pStream = pChannel->getStreamByHandle(frame->bufs[i]->stream_id); 310 if (pStream != NULL) { 311 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) { 312 pMetaFrame = frame->bufs[i]; 313 break; 314 } 315 } 316 } 317 318 if (NULL == pMetaFrame) { 319 LOGE("No metadata buffer found in scene select super buffer"); 320 return NO_INIT; 321 } 322 323 metadata_buffer_t *pMetaData = (metadata_buffer_t *)pMetaFrame->buffer; 324 325 IF_META_AVAILABLE(cam_scene_mode_type, scene, CAM_INTF_META_CURRENT_SCENE, pMetaData) { 326 if ((*scene == selectedScene) && 327 (mDataCb != NULL) && 328 (msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_FRAME) > 0)) { 329 mm_camera_buf_def_t *preview_frame = NULL; 330 for (uint32_t i = 0; i < frame->num_bufs; i++) { 331 pStream = pChannel->getStreamByHandle(frame->bufs[i]->stream_id); 332 if (pStream != NULL) { 333 if (pStream->isTypeOf(CAM_STREAM_TYPE_PREVIEW)) { 334 preview_frame = frame->bufs[i]; 335 break; 336 } 337 } 338 } 339 if (preview_frame) { 340 QCameraGrallocMemory *memory = (QCameraGrallocMemory *)preview_frame->mem_info; 341 uint32_t idx = preview_frame->buf_idx; 342 preview_frame->cache_flags |= CPU_HAS_READ; 343 rc = sendPreviewCallback(pStream, memory, idx); 344 if (NO_ERROR != rc) { 345 LOGE("Error triggering scene select preview callback"); 346 } else { 347 mParameters.setSelectedScene(CAM_SCENE_MODE_MAX); 348 } 349 } else { 350 LOGE("No preview buffer found in scene select super buffer"); 351 return NO_INIT; 352 } 353 } 354 } else { 355 LOGE("No current scene metadata!"); 356 rc = NO_INIT; 357 } 358 359 return rc; 360 } 361 362 /*=========================================================================== 363 * FUNCTION : capture_channel_cb_routine 364 * 365 * DESCRIPTION: helper function to handle snapshot superbuf callback directly from 366 * mm-camera-interface 367 * 368 * PARAMETERS : 369 * @recvd_frame : received super buffer 370 * @userdata : user data ptr 371 * 372 * RETURN : None 373 * 374 * NOTE : recvd_frame will be released after this call by caller, so if 375 * async operation needed for recvd_frame, it's our responsibility 376 * to save a copy for this variable to be used later. 377 *==========================================================================*/ 378 void QCamera2HardwareInterface::capture_channel_cb_routine(mm_camera_super_buf_t *recvd_frame, 379 void *userdata) 380 { 381 KPI_ATRACE_CALL(); 382 char value[PROPERTY_VALUE_MAX]; 383 LOGH("[KPI Perf]: E PROFILE_YUV_CB_TO_HAL"); 384 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 385 if (pme == NULL || 386 pme->mCameraHandle == NULL || 387 pme->mCameraHandle->camera_handle != recvd_frame->camera_handle){ 388 LOGE("camera obj not valid"); 389 return; 390 } 391 392 QCameraChannel *pChannel = pme->m_channels[QCAMERA_CH_TYPE_CAPTURE]; 393 if (pChannel == NULL || 394 pChannel->getMyHandle() != recvd_frame->ch_id) { 395 LOGE("Capture channel doesn't exist, return here"); 396 return; 397 } 398 399 // save a copy for the superbuf 400 mm_camera_super_buf_t* frame = 401 (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t)); 402 if (frame == NULL) { 403 LOGE("Error allocating memory to save received_frame structure."); 404 pChannel->bufDone(recvd_frame); 405 return; 406 } 407 *frame = *recvd_frame; 408 409 if (recvd_frame->num_bufs > 0) { 410 LOGI("[KPI Perf]: superbuf frame_idx %d", 411 recvd_frame->bufs[0]->frame_idx); 412 } 413 414 for ( uint32_t i= 0 ; i < recvd_frame->num_bufs ; i++ ) { 415 if ( recvd_frame->bufs[i]->stream_type == CAM_STREAM_TYPE_SNAPSHOT ) { 416 mm_camera_buf_def_t * yuv_frame = recvd_frame->bufs[i]; 417 QCameraStream *pStream = pChannel->getStreamByHandle(yuv_frame->stream_id); 418 if ( NULL != pStream ) { 419 pme->dumpFrameToFile(pStream, yuv_frame, QCAMERA_DUMP_FRM_INPUT_REPROCESS); 420 } 421 break; 422 } 423 } 424 425 property_get("persist.camera.dumpmetadata", value, "0"); 426 int32_t enabled = atoi(value); 427 if (enabled) { 428 mm_camera_buf_def_t *pMetaFrame = NULL; 429 QCameraStream *pStream = NULL; 430 for (uint32_t i = 0; i < frame->num_bufs; i++) { 431 pStream = pChannel->getStreamByHandle(frame->bufs[i]->stream_id); 432 if (pStream != NULL) { 433 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) { 434 pMetaFrame = frame->bufs[i]; //find the metadata 435 if (pMetaFrame != NULL && 436 ((metadata_buffer_t *)pMetaFrame->buffer)->is_tuning_params_valid) { 437 pme->dumpMetadataToFile(pStream, pMetaFrame, (char *) "Snapshot"); 438 } 439 break; 440 } 441 } 442 } 443 } 444 445 // Wait on Postproc initialization if needed 446 // then send to postprocessor 447 if ((NO_ERROR != pme->waitDeferredWork(pme->mReprocJob)) || 448 (NO_ERROR != pme->m_postprocessor.processData(frame))) { 449 LOGE("Failed to trigger process data"); 450 pChannel->bufDone(recvd_frame); 451 free(frame); 452 frame = NULL; 453 return; 454 } 455 456 /* START of test register face image for face authentication */ 457 #ifdef QCOM_TEST_FACE_REGISTER_FACE 458 static uint8_t bRunFaceReg = 1; 459 460 if (bRunFaceReg > 0) { 461 // find snapshot frame 462 QCameraStream *main_stream = NULL; 463 mm_camera_buf_def_t *main_frame = NULL; 464 for (int i = 0; i < recvd_frame->num_bufs; i++) { 465 QCameraStream *pStream = 466 pChannel->getStreamByHandle(recvd_frame->bufs[i]->stream_id); 467 if (pStream != NULL) { 468 if (pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT)) { 469 main_stream = pStream; 470 main_frame = recvd_frame->bufs[i]; 471 break; 472 } 473 } 474 } 475 if (main_stream != NULL && main_frame != NULL) { 476 int32_t faceId = -1; 477 cam_pp_offline_src_config_t config; 478 memset(&config, 0, sizeof(cam_pp_offline_src_config_t)); 479 config.num_of_bufs = 1; 480 main_stream->getFormat(config.input_fmt); 481 main_stream->getFrameDimension(config.input_dim); 482 main_stream->getFrameOffset(config.input_buf_planes.plane_info); 483 LOGH("DEBUG: registerFaceImage E"); 484 int32_t rc = pme->registerFaceImage(main_frame->buffer, &config, faceId); 485 LOGH("DEBUG: registerFaceImage X, ret=%d, faceId=%d", rc, faceId); 486 bRunFaceReg = 0; 487 } 488 } 489 490 #endif 491 /* END of test register face image for face authentication */ 492 493 LOGH("[KPI Perf]: X"); 494 } 495 #ifdef TARGET_TS_MAKEUP 496 bool QCamera2HardwareInterface::TsMakeupProcess_Preview(mm_camera_buf_def_t *pFrame, 497 QCameraStream * pStream) { 498 LOGD("begin"); 499 bool bRet = false; 500 if (pStream == NULL || pFrame == NULL) { 501 bRet = false; 502 LOGH("pStream == NULL || pFrame == NULL"); 503 } else { 504 bRet = TsMakeupProcess(pFrame, pStream, mFaceRect); 505 } 506 LOGD("end bRet = %d ",bRet); 507 return bRet; 508 } 509 510 bool QCamera2HardwareInterface::TsMakeupProcess_Snapshot(mm_camera_buf_def_t *pFrame, 511 QCameraStream * pStream) { 512 LOGD("begin"); 513 bool bRet = false; 514 if (pStream == NULL || pFrame == NULL) { 515 bRet = false; 516 LOGH("pStream == NULL || pFrame == NULL"); 517 } else { 518 cam_frame_len_offset_t offset; 519 memset(&offset, 0, sizeof(cam_frame_len_offset_t)); 520 pStream->getFrameOffset(offset); 521 522 cam_dimension_t dim; 523 pStream->getFrameDimension(dim); 524 525 unsigned char *yBuf = (unsigned char*)pFrame->buffer; 526 unsigned char *uvBuf = yBuf + offset.mp[0].len; 527 TSMakeupDataEx inMakeupData; 528 inMakeupData.frameWidth = dim.width; 529 inMakeupData.frameHeight = dim.height; 530 inMakeupData.yBuf = yBuf; 531 inMakeupData.uvBuf = uvBuf; 532 inMakeupData.yStride = offset.mp[0].stride; 533 inMakeupData.uvStride = offset.mp[1].stride; 534 LOGD("detect begin"); 535 TSHandle fd_handle = ts_detectface_create_context(); 536 if (fd_handle != NULL) { 537 cam_format_t fmt; 538 pStream->getFormat(fmt); 539 int iret = ts_detectface_detectEx(fd_handle, &inMakeupData); 540 LOGD("ts_detectface_detect iret = %d",iret); 541 if (iret <= 0) { 542 bRet = false; 543 } else { 544 TSRect faceRect; 545 memset(&faceRect,-1,sizeof(TSRect)); 546 iret = ts_detectface_get_face_info(fd_handle, 0, &faceRect, NULL,NULL,NULL); 547 LOGD("ts_detectface_get_face_info iret=%d,faceRect.left=%ld," 548 "faceRect.top=%ld,faceRect.right=%ld,faceRect.bottom=%ld" 549 ,iret,faceRect.left,faceRect.top,faceRect.right,faceRect.bottom); 550 bRet = TsMakeupProcess(pFrame,pStream,faceRect); 551 } 552 ts_detectface_destroy_context(&fd_handle); 553 fd_handle = NULL; 554 } else { 555 LOGH("fd_handle == NULL"); 556 } 557 LOGD("detect end"); 558 } 559 LOGD("end bRet = %d ",bRet); 560 return bRet; 561 } 562 563 bool QCamera2HardwareInterface::TsMakeupProcess(mm_camera_buf_def_t *pFrame, 564 QCameraStream * pStream,TSRect& faceRect) { 565 bool bRet = false; 566 LOGD("begin"); 567 if (pStream == NULL || pFrame == NULL) { 568 LOGH("pStream == NULL || pFrame == NULL "); 569 return false; 570 } 571 572 int whiteLevel, cleanLevel; 573 bool enableMakeup = (faceRect.left > -1) && 574 (mParameters.getTsMakeupInfo(whiteLevel, cleanLevel)); 575 if (enableMakeup) { 576 cam_dimension_t dim; 577 cam_frame_len_offset_t offset; 578 pStream->getFrameDimension(dim); 579 pStream->getFrameOffset(offset); 580 unsigned char *tempOriBuf = NULL; 581 582 tempOriBuf = (unsigned char*)pFrame->buffer; 583 unsigned char *yBuf = tempOriBuf; 584 unsigned char *uvBuf = tempOriBuf + offset.mp[0].len; 585 unsigned char *tmpBuf = new unsigned char[offset.frame_len]; 586 if (tmpBuf == NULL) { 587 LOGH("tmpBuf == NULL "); 588 return false; 589 } 590 TSMakeupDataEx inMakeupData, outMakeupData; 591 whiteLevel = whiteLevel <= 0 ? 0 : (whiteLevel >= 100 ? 100 : whiteLevel); 592 cleanLevel = cleanLevel <= 0 ? 0 : (cleanLevel >= 100 ? 100 : cleanLevel); 593 inMakeupData.frameWidth = dim.width; // NV21 Frame width > 0 594 inMakeupData.frameHeight = dim.height; // NV21 Frame height > 0 595 inMakeupData.yBuf = yBuf; // Y buffer pointer 596 inMakeupData.uvBuf = uvBuf; // VU buffer pointer 597 inMakeupData.yStride = offset.mp[0].stride; 598 inMakeupData.uvStride = offset.mp[1].stride; 599 outMakeupData.frameWidth = dim.width; // NV21 Frame width > 0 600 outMakeupData.frameHeight = dim.height; // NV21 Frame height > 0 601 outMakeupData.yBuf = tmpBuf; // Y buffer pointer 602 outMakeupData.uvBuf = tmpBuf + offset.mp[0].len; // VU buffer pointer 603 outMakeupData.yStride = offset.mp[0].stride; 604 outMakeupData.uvStride = offset.mp[1].stride; 605 LOGD("faceRect:left 2:%ld,,right:%ld,,top:%ld,,bottom:%ld,,Level:%dx%d", 606 faceRect.left,faceRect.right,faceRect.top,faceRect.bottom,cleanLevel,whiteLevel); 607 ts_makeup_skin_beautyEx(&inMakeupData, &outMakeupData, &(faceRect),cleanLevel,whiteLevel); 608 memcpy((unsigned char*)pFrame->buffer, tmpBuf, offset.frame_len); 609 QCameraMemory *memory = (QCameraMemory *)pFrame->mem_info; 610 memory->cleanCache(pFrame->buf_idx); 611 if (tmpBuf != NULL) { 612 delete[] tmpBuf; 613 tmpBuf = NULL; 614 } 615 } 616 LOGD("end bRet = %d ",bRet); 617 return bRet; 618 } 619 #endif 620 /*=========================================================================== 621 * FUNCTION : postproc_channel_cb_routine 622 * 623 * DESCRIPTION: helper function to handle postprocess superbuf callback directly from 624 * mm-camera-interface 625 * 626 * PARAMETERS : 627 * @recvd_frame : received super buffer 628 * @userdata : user data ptr 629 * 630 * RETURN : None 631 * 632 * NOTE : recvd_frame will be released after this call by caller, so if 633 * async operation needed for recvd_frame, it's our responsibility 634 * to save a copy for this variable to be used later. 635 *==========================================================================*/ 636 void QCamera2HardwareInterface::postproc_channel_cb_routine(mm_camera_super_buf_t *recvd_frame, 637 void *userdata) 638 { 639 ATRACE_CALL(); 640 LOGH("[KPI Perf]: E"); 641 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 642 if (pme == NULL || 643 pme->mCameraHandle == NULL || 644 pme->mCameraHandle->camera_handle != recvd_frame->camera_handle){ 645 LOGE("camera obj not valid"); 646 return; 647 } 648 649 // save a copy for the superbuf 650 mm_camera_super_buf_t* frame = 651 (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t)); 652 if (frame == NULL) { 653 LOGE("Error allocating memory to save received_frame structure."); 654 return; 655 } 656 *frame = *recvd_frame; 657 658 if (recvd_frame->num_bufs > 0) { 659 LOGI("[KPI Perf]: frame_idx %d", recvd_frame->bufs[0]->frame_idx); 660 } 661 // Wait on JPEG create session 662 pme->waitDeferredWork(pme->mJpegJob); 663 664 // send to postprocessor 665 pme->m_postprocessor.processPPData(frame); 666 667 ATRACE_INT("Camera:Reprocess", 0); 668 LOGH("[KPI Perf]: X"); 669 } 670 671 /*=========================================================================== 672 * FUNCTION : synchronous_stream_cb_routine 673 * 674 * DESCRIPTION: Function to handle STREAM SYNC CALLBACKS 675 * 676 * PARAMETERS : 677 * @super_frame : received super buffer 678 * @stream : stream object 679 * @userdata : user data ptr 680 * 681 * RETURN : None 682 * 683 * NOTE : This Function is excecuted in mm-interface context. 684 * Avoid adding latency on this thread. 685 *==========================================================================*/ 686 void QCamera2HardwareInterface::synchronous_stream_cb_routine( 687 mm_camera_super_buf_t *super_frame, QCameraStream * stream, 688 void *userdata) 689 { 690 nsecs_t frameTime = 0, mPreviewTimestamp = 0; 691 int err = NO_ERROR; 692 693 ATRACE_CALL(); 694 LOGH("[KPI Perf] : BEGIN"); 695 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 696 QCameraGrallocMemory *memory = NULL; 697 698 if (pme == NULL) { 699 LOGE("Invalid hardware object"); 700 return; 701 } 702 if (super_frame == NULL) { 703 LOGE("Invalid super buffer"); 704 return; 705 } 706 mm_camera_buf_def_t *frame = super_frame->bufs[0]; 707 if (NULL == frame) { 708 LOGE("Frame is NULL"); 709 return; 710 } 711 712 if (stream->getMyType() != CAM_STREAM_TYPE_PREVIEW) { 713 LOGE("This is only for PREVIEW stream for now"); 714 return; 715 } 716 717 if(pme->m_bPreviewStarted) { 718 LOGI("[KPI Perf] : PROFILE_FIRST_PREVIEW_FRAME"); 719 pme->m_bPreviewStarted = false; 720 } 721 722 if (!pme->needProcessPreviewFrame(frame->frame_idx)) { 723 pthread_mutex_lock(&pme->mGrallocLock); 724 pme->mLastPreviewFrameID = frame->frame_idx; 725 pthread_mutex_unlock(&pme->mGrallocLock); 726 LOGH("preview is not running, no need to process"); 727 return; 728 } 729 730 frameTime = nsecs_t(frame->ts.tv_sec) * 1000000000LL + frame->ts.tv_nsec; 731 // Calculate the future presentation time stamp for displaying frames at regular interval 732 #if 0 // Temporary removing the dependency on libgui 733 mPreviewTimestamp = pme->mCameraDisplay.computePresentationTimeStamp(frameTime); 734 #endif 735 stream->mStreamTimestamp = frameTime; 736 memory = (QCameraGrallocMemory *)super_frame->bufs[0]->mem_info; 737 738 #ifdef TARGET_TS_MAKEUP 739 pme->TsMakeupProcess_Preview(frame,stream); 740 #endif 741 742 // Enqueue buffer to gralloc. 743 uint32_t idx = frame->buf_idx; 744 LOGD("%p Enqueue Buffer to display %d frame Time = %lld Display Time = %lld", 745 pme, idx, frameTime, mPreviewTimestamp); 746 err = memory->enqueueBuffer(idx, mPreviewTimestamp); 747 748 if (err == NO_ERROR) { 749 pthread_mutex_lock(&pme->mGrallocLock); 750 pme->mLastPreviewFrameID = frame->frame_idx; 751 pme->mEnqueuedBuffers++; 752 pthread_mutex_unlock(&pme->mGrallocLock); 753 } else { 754 LOGE("Enqueue Buffer failed"); 755 } 756 757 LOGH("[KPI Perf] : END"); 758 return; 759 } 760 761 /*=========================================================================== 762 * FUNCTION : preview_stream_cb_routine 763 * 764 * DESCRIPTION: helper function to handle preview frame from preview stream in 765 * normal case with display. 766 * 767 * PARAMETERS : 768 * @super_frame : received super buffer 769 * @stream : stream object 770 * @userdata : user data ptr 771 * 772 * RETURN : None 773 * 774 * NOTE : caller passes the ownership of super_frame, it's our 775 * responsibility to free super_frame once it's done. The new 776 * preview frame will be sent to display, and an older frame 777 * will be dequeued from display and needs to be returned back 778 * to kernel for future use. 779 *==========================================================================*/ 780 void QCamera2HardwareInterface::preview_stream_cb_routine(mm_camera_super_buf_t *super_frame, 781 QCameraStream * stream, 782 void *userdata) 783 { 784 KPI_ATRACE_CALL(); 785 LOGH("[KPI Perf] : BEGIN"); 786 int err = NO_ERROR; 787 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 788 QCameraGrallocMemory *memory = (QCameraGrallocMemory *)super_frame->bufs[0]->mem_info; 789 uint8_t dequeueCnt = 0; 790 791 if (pme == NULL) { 792 LOGE("Invalid hardware object"); 793 free(super_frame); 794 return; 795 } 796 if (memory == NULL) { 797 LOGE("Invalid memory object"); 798 free(super_frame); 799 return; 800 } 801 802 mm_camera_buf_def_t *frame = super_frame->bufs[0]; 803 if (NULL == frame) { 804 LOGE("preview frame is NLUL"); 805 free(super_frame); 806 return; 807 } 808 809 // For instant capture and for instant AEC, keep track of the frame counter. 810 // This count will be used to check against the corresponding bound values. 811 if (pme->mParameters.isInstantAECEnabled() || 812 pme->mParameters.isInstantCaptureEnabled()) { 813 pme->mInstantAecFrameCount++; 814 } 815 816 pthread_mutex_lock(&pme->mGrallocLock); 817 if (!stream->isSyncCBEnabled()) { 818 pme->mLastPreviewFrameID = frame->frame_idx; 819 } 820 if (((!stream->isSyncCBEnabled()) && 821 (!pme->needProcessPreviewFrame(frame->frame_idx))) || 822 ((stream->isSyncCBEnabled()) && 823 (memory->isBufOwnedByCamera(frame->buf_idx)))) { 824 //If buffer owned by camera, then it is not enqueued to display. 825 // bufDone it back to backend. 826 pthread_mutex_unlock(&pme->mGrallocLock); 827 LOGH("preview is not running, no need to process"); 828 stream->bufDone(frame->buf_idx); 829 free(super_frame); 830 return; 831 } else { 832 pthread_mutex_unlock(&pme->mGrallocLock); 833 } 834 835 if (pme->needDebugFps()) { 836 pme->debugShowPreviewFPS(); 837 } 838 839 uint32_t idx = frame->buf_idx; 840 841 pme->dumpFrameToFile(stream, frame, QCAMERA_DUMP_FRM_PREVIEW); 842 843 if(pme->m_bPreviewStarted) { 844 LOGI("[KPI Perf] : PROFILE_FIRST_PREVIEW_FRAME"); 845 pme->m_bPreviewStarted = false ; 846 } 847 848 if (!stream->isSyncCBEnabled()) { 849 LOGD("Enqueue Buffer to display %d", idx); 850 #ifdef TARGET_TS_MAKEUP 851 pme->TsMakeupProcess_Preview(frame,stream); 852 #endif 853 err = memory->enqueueBuffer(idx); 854 855 if (err == NO_ERROR) { 856 pthread_mutex_lock(&pme->mGrallocLock); 857 pme->mEnqueuedBuffers++; 858 dequeueCnt = pme->mEnqueuedBuffers; 859 pthread_mutex_unlock(&pme->mGrallocLock); 860 } else { 861 LOGE("Enqueue Buffer failed"); 862 } 863 } else { 864 pthread_mutex_lock(&pme->mGrallocLock); 865 dequeueCnt = pme->mEnqueuedBuffers; 866 pthread_mutex_unlock(&pme->mGrallocLock); 867 } 868 869 // Display the buffer. 870 LOGD("%p displayBuffer %d E", pme, idx); 871 uint8_t numMapped = memory->getMappable(); 872 873 for (uint8_t i = 0; i < dequeueCnt; i++) { 874 int dequeuedIdx = memory->dequeueBuffer(); 875 if (dequeuedIdx < 0 || dequeuedIdx >= memory->getCnt()) { 876 LOGE("Invalid dequeued buffer index %d from display", 877 dequeuedIdx); 878 break; 879 } else { 880 pthread_mutex_lock(&pme->mGrallocLock); 881 pme->mEnqueuedBuffers--; 882 pthread_mutex_unlock(&pme->mGrallocLock); 883 if (dequeuedIdx >= numMapped) { 884 // This buffer has not yet been mapped to the backend 885 err = stream->mapNewBuffer((uint32_t)dequeuedIdx); 886 if (memory->checkIfAllBuffersMapped()) { 887 // check if mapping is done for all the buffers 888 // Signal the condition for create jpeg session 889 Mutex::Autolock l(pme->mMapLock); 890 pme->mMapCond.signal(); 891 LOGH("Mapping done for all bufs"); 892 } else { 893 LOGH("All buffers are not yet mapped"); 894 } 895 } 896 } 897 898 if (err < 0) { 899 LOGE("buffer mapping failed %d", err); 900 } else { 901 // Return dequeued buffer back to driver 902 err = stream->bufDone((uint32_t)dequeuedIdx); 903 if ( err < 0) { 904 LOGW("stream bufDone failed %d", err); 905 } 906 } 907 } 908 909 // Handle preview data callback 910 if (pme->m_channels[QCAMERA_CH_TYPE_CALLBACK] == NULL) { 911 if (pme->needSendPreviewCallback() && 912 (!pme->mParameters.isSceneSelectionEnabled())) { 913 frame->cache_flags |= CPU_HAS_READ; 914 int32_t rc = pme->sendPreviewCallback(stream, memory, idx); 915 if (NO_ERROR != rc) { 916 LOGW("Preview callback was not sent succesfully"); 917 } 918 } 919 } 920 921 free(super_frame); 922 LOGH("[KPI Perf] : END"); 923 return; 924 } 925 926 /*=========================================================================== 927 * FUNCTION : sendPreviewCallback 928 * 929 * DESCRIPTION: helper function for triggering preview callbacks 930 * 931 * PARAMETERS : 932 * @stream : stream object 933 * @memory : Stream memory allocator 934 * @idx : buffer index 935 * 936 * RETURN : int32_t type of status 937 * NO_ERROR -- success 938 * none-zero failure code 939 *==========================================================================*/ 940 int32_t QCamera2HardwareInterface::sendPreviewCallback(QCameraStream *stream, 941 QCameraMemory *memory, uint32_t idx) 942 { 943 camera_memory_t *previewMem = NULL; 944 camera_memory_t *data = NULL; 945 camera_memory_t *dataToApp = NULL; 946 size_t previewBufSize = 0; 947 size_t previewBufSizeFromCallback = 0; 948 cam_dimension_t preview_dim; 949 cam_format_t previewFmt; 950 int32_t rc = NO_ERROR; 951 int32_t yStride = 0; 952 int32_t yScanline = 0; 953 int32_t uvStride = 0; 954 int32_t uvScanline = 0; 955 int32_t uStride = 0; 956 int32_t uScanline = 0; 957 int32_t vStride = 0; 958 int32_t vScanline = 0; 959 int32_t yStrideToApp = 0; 960 int32_t uvStrideToApp = 0; 961 int32_t yScanlineToApp = 0; 962 int32_t uvScanlineToApp = 0; 963 int32_t srcOffset = 0; 964 int32_t dstOffset = 0; 965 int32_t srcBaseOffset = 0; 966 int32_t dstBaseOffset = 0; 967 int i; 968 969 if ((NULL == stream) || (NULL == memory)) { 970 LOGE("Invalid preview callback input"); 971 return BAD_VALUE; 972 } 973 974 cam_stream_info_t *streamInfo = 975 reinterpret_cast<cam_stream_info_t *>(stream->getStreamInfoBuf()->getPtr(0)); 976 if (NULL == streamInfo) { 977 LOGE("Invalid streamInfo"); 978 return BAD_VALUE; 979 } 980 981 stream->getFrameDimension(preview_dim); 982 stream->getFormat(previewFmt); 983 984 yStrideToApp = preview_dim.width; 985 yScanlineToApp = preview_dim.height; 986 uvStrideToApp = yStrideToApp; 987 uvScanlineToApp = yScanlineToApp / 2; 988 989 /* The preview buffer size in the callback should be 990 * (width*height*bytes_per_pixel). As all preview formats we support, 991 * use 12 bits per pixel, buffer size = previewWidth * previewHeight * 3/2. 992 * We need to put a check if some other formats are supported in future. */ 993 if ((previewFmt == CAM_FORMAT_YUV_420_NV21) || 994 (previewFmt == CAM_FORMAT_YUV_420_NV12) || 995 (previewFmt == CAM_FORMAT_YUV_420_YV12) || 996 (previewFmt == CAM_FORMAT_YUV_420_NV12_VENUS) || 997 (previewFmt == CAM_FORMAT_YUV_420_NV21_VENUS) || 998 (previewFmt == CAM_FORMAT_YUV_420_NV21_ADRENO)) { 999 if(previewFmt == CAM_FORMAT_YUV_420_YV12) { 1000 yStride = streamInfo->buf_planes.plane_info.mp[0].stride; 1001 yScanline = streamInfo->buf_planes.plane_info.mp[0].scanline; 1002 uStride = streamInfo->buf_planes.plane_info.mp[1].stride; 1003 uScanline = streamInfo->buf_planes.plane_info.mp[1].scanline; 1004 vStride = streamInfo->buf_planes.plane_info.mp[2].stride; 1005 vScanline = streamInfo->buf_planes.plane_info.mp[2].scanline; 1006 1007 previewBufSize = (size_t) 1008 (yStride * yScanline + uStride * uScanline + vStride * vScanline); 1009 previewBufSizeFromCallback = previewBufSize; 1010 } else { 1011 yStride = streamInfo->buf_planes.plane_info.mp[0].stride; 1012 yScanline = streamInfo->buf_planes.plane_info.mp[0].scanline; 1013 uvStride = streamInfo->buf_planes.plane_info.mp[1].stride; 1014 uvScanline = streamInfo->buf_planes.plane_info.mp[1].scanline; 1015 1016 previewBufSize = (size_t) 1017 ((yStrideToApp * yScanlineToApp) + (uvStrideToApp * uvScanlineToApp)); 1018 1019 previewBufSizeFromCallback = (size_t) 1020 ((yStride * yScanline) + (uvStride * uvScanline)); 1021 } 1022 if(previewBufSize == previewBufSizeFromCallback) { 1023 previewMem = mGetMemory(memory->getFd(idx), 1024 previewBufSize, 1, mCallbackCookie); 1025 if (!previewMem || !previewMem->data) { 1026 LOGE("mGetMemory failed.\n"); 1027 return NO_MEMORY; 1028 } else { 1029 data = previewMem; 1030 } 1031 } else { 1032 data = memory->getMemory(idx, false); 1033 dataToApp = mGetMemory(-1, previewBufSize, 1, mCallbackCookie); 1034 if (!dataToApp || !dataToApp->data) { 1035 LOGE("mGetMemory failed.\n"); 1036 return NO_MEMORY; 1037 } 1038 1039 for (i = 0; i < preview_dim.height; i++) { 1040 srcOffset = i * yStride; 1041 dstOffset = i * yStrideToApp; 1042 1043 memcpy((unsigned char *) dataToApp->data + dstOffset, 1044 (unsigned char *) data->data + srcOffset, 1045 (size_t)yStrideToApp); 1046 } 1047 1048 srcBaseOffset = yStride * yScanline; 1049 dstBaseOffset = yStrideToApp * yScanlineToApp; 1050 1051 for (i = 0; i < preview_dim.height/2; i++) { 1052 srcOffset = i * uvStride + srcBaseOffset; 1053 dstOffset = i * uvStrideToApp + dstBaseOffset; 1054 1055 memcpy((unsigned char *) dataToApp->data + dstOffset, 1056 (unsigned char *) data->data + srcOffset, 1057 (size_t)yStrideToApp); 1058 } 1059 } 1060 } else { 1061 /*Invalid Buffer content. But can be used as a first preview frame trigger in 1062 framework/app */ 1063 previewBufSize = (size_t) 1064 ((yStrideToApp * yScanlineToApp) + 1065 (uvStrideToApp * uvScanlineToApp)); 1066 previewBufSizeFromCallback = 0; 1067 LOGW("Invalid preview format. Buffer content cannot be processed size = %d", 1068 previewBufSize); 1069 dataToApp = mGetMemory(-1, previewBufSize, 1, mCallbackCookie); 1070 if (!dataToApp || !dataToApp->data) { 1071 LOGE("mGetMemory failed.\n"); 1072 return NO_MEMORY; 1073 } 1074 } 1075 qcamera_callback_argm_t cbArg; 1076 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 1077 cbArg.cb_type = QCAMERA_DATA_CALLBACK; 1078 cbArg.msg_type = CAMERA_MSG_PREVIEW_FRAME; 1079 if (previewBufSize != 0 && previewBufSizeFromCallback != 0 && 1080 previewBufSize == previewBufSizeFromCallback) { 1081 cbArg.data = data; 1082 } else { 1083 cbArg.data = dataToApp; 1084 } 1085 if ( previewMem ) { 1086 cbArg.user_data = previewMem; 1087 cbArg.release_cb = releaseCameraMemory; 1088 } else if (dataToApp) { 1089 cbArg.user_data = dataToApp; 1090 cbArg.release_cb = releaseCameraMemory; 1091 } 1092 cbArg.cookie = this; 1093 rc = m_cbNotifier.notifyCallback(cbArg); 1094 if (rc != NO_ERROR) { 1095 LOGW("fail sending notification"); 1096 if (previewMem) { 1097 previewMem->release(previewMem); 1098 } else if (dataToApp) { 1099 dataToApp->release(dataToApp); 1100 } 1101 } 1102 1103 return rc; 1104 } 1105 1106 /*=========================================================================== 1107 * FUNCTION : nodisplay_preview_stream_cb_routine 1108 * 1109 * DESCRIPTION: helper function to handle preview frame from preview stream in 1110 * no-display case 1111 * 1112 * PARAMETERS : 1113 * @super_frame : received super buffer 1114 * @stream : stream object 1115 * @userdata : user data ptr 1116 * 1117 * RETURN : None 1118 * 1119 * NOTE : caller passes the ownership of super_frame, it's our 1120 * responsibility to free super_frame once it's done. 1121 *==========================================================================*/ 1122 void QCamera2HardwareInterface::nodisplay_preview_stream_cb_routine( 1123 mm_camera_super_buf_t *super_frame, 1124 QCameraStream *stream, 1125 void * userdata) 1126 { 1127 ATRACE_CALL(); 1128 LOGH("[KPI Perf] E"); 1129 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 1130 if (pme == NULL || 1131 pme->mCameraHandle == NULL || 1132 pme->mCameraHandle->camera_handle != super_frame->camera_handle){ 1133 LOGE("camera obj not valid"); 1134 // simply free super frame 1135 free(super_frame); 1136 return; 1137 } 1138 mm_camera_buf_def_t *frame = super_frame->bufs[0]; 1139 if (NULL == frame) { 1140 LOGE("preview frame is NULL"); 1141 free(super_frame); 1142 return; 1143 } 1144 1145 if (!pme->needProcessPreviewFrame(frame->frame_idx)) { 1146 LOGH("preview is not running, no need to process"); 1147 stream->bufDone(frame->buf_idx); 1148 free(super_frame); 1149 return; 1150 } 1151 1152 if (pme->needDebugFps()) { 1153 pme->debugShowPreviewFPS(); 1154 } 1155 1156 QCameraMemory *previewMemObj = (QCameraMemory *)frame->mem_info; 1157 camera_memory_t *preview_mem = NULL; 1158 if (previewMemObj != NULL) { 1159 preview_mem = previewMemObj->getMemory(frame->buf_idx, false); 1160 } 1161 if (NULL != previewMemObj && NULL != preview_mem) { 1162 pme->dumpFrameToFile(stream, frame, QCAMERA_DUMP_FRM_PREVIEW); 1163 1164 if ((pme->needProcessPreviewFrame(frame->frame_idx)) && 1165 pme->needSendPreviewCallback() && 1166 (pme->getRelatedCamSyncInfo()->mode != CAM_MODE_SECONDARY)) { 1167 qcamera_callback_argm_t cbArg; 1168 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 1169 cbArg.cb_type = QCAMERA_DATA_CALLBACK; 1170 cbArg.msg_type = CAMERA_MSG_PREVIEW_FRAME; 1171 cbArg.data = preview_mem; 1172 cbArg.user_data = (void *) &frame->buf_idx; 1173 cbArg.cookie = stream; 1174 cbArg.release_cb = returnStreamBuffer; 1175 // Preset cache flags to be handled when the buffer comes back 1176 frame->cache_flags |= CPU_HAS_READ; 1177 int32_t rc = pme->m_cbNotifier.notifyCallback(cbArg); 1178 if (rc != NO_ERROR) { 1179 LOGE ("fail sending data notify"); 1180 stream->bufDone(frame->buf_idx); 1181 } 1182 } else { 1183 stream->bufDone(frame->buf_idx); 1184 } 1185 } 1186 free(super_frame); 1187 LOGH("[KPI Perf] X"); 1188 } 1189 1190 /*=========================================================================== 1191 * FUNCTION : rdi_mode_stream_cb_routine 1192 * 1193 * DESCRIPTION: helper function to handle RDI frame from preview stream in 1194 * rdi mode case 1195 * 1196 * PARAMETERS : 1197 * @super_frame : received super buffer 1198 * @stream : stream object 1199 * @userdata : user data ptr 1200 * 1201 * RETURN : None 1202 * 1203 * NOTE : caller passes the ownership of super_frame, it's our 1204 * responsibility to free super_frame once it's done. 1205 *==========================================================================*/ 1206 void QCamera2HardwareInterface::rdi_mode_stream_cb_routine( 1207 mm_camera_super_buf_t *super_frame, 1208 QCameraStream *stream, 1209 void * userdata) 1210 { 1211 ATRACE_CALL(); 1212 LOGH("RDI_DEBUG Enter"); 1213 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 1214 if (pme == NULL || 1215 pme->mCameraHandle == NULL || 1216 pme->mCameraHandle->camera_handle != super_frame->camera_handle){ 1217 LOGE("camera obj not valid"); 1218 free(super_frame); 1219 return; 1220 } 1221 mm_camera_buf_def_t *frame = super_frame->bufs[0]; 1222 if (NULL == frame) { 1223 LOGE("preview frame is NLUL"); 1224 goto end; 1225 } 1226 if (!pme->needProcessPreviewFrame(frame->frame_idx)) { 1227 LOGE("preview is not running, no need to process"); 1228 stream->bufDone(frame->buf_idx); 1229 goto end; 1230 } 1231 if (pme->needDebugFps()) { 1232 pme->debugShowPreviewFPS(); 1233 } 1234 // Non-secure Mode 1235 if (!pme->isSecureMode()) { 1236 QCameraMemory *previewMemObj = (QCameraMemory *)frame->mem_info; 1237 if (NULL == previewMemObj) { 1238 LOGE("previewMemObj is NULL"); 1239 stream->bufDone(frame->buf_idx); 1240 goto end; 1241 } 1242 1243 camera_memory_t *preview_mem = previewMemObj->getMemory(frame->buf_idx, false); 1244 if (NULL != preview_mem) { 1245 previewMemObj->cleanCache(frame->buf_idx); 1246 // Dump RAW frame 1247 pme->dumpFrameToFile(stream, frame, QCAMERA_DUMP_FRM_RAW); 1248 // Notify Preview callback frame 1249 if (pme->needProcessPreviewFrame(frame->frame_idx) && 1250 pme->mDataCb != NULL && 1251 pme->msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_FRAME) > 0) { 1252 qcamera_callback_argm_t cbArg; 1253 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 1254 cbArg.cb_type = QCAMERA_DATA_CALLBACK; 1255 cbArg.msg_type = CAMERA_MSG_PREVIEW_FRAME; 1256 cbArg.data = preview_mem; 1257 cbArg.user_data = (void *) &frame->buf_idx; 1258 cbArg.cookie = stream; 1259 cbArg.release_cb = returnStreamBuffer; 1260 // Preset cache flags to be handled when the buffer comes back 1261 frame->cache_flags |= CPU_HAS_READ; 1262 pme->m_cbNotifier.notifyCallback(cbArg); 1263 } else { 1264 LOGE("preview_mem is NULL"); 1265 stream->bufDone(frame->buf_idx); 1266 } 1267 } 1268 else { 1269 LOGE("preview_mem is NULL"); 1270 stream->bufDone(frame->buf_idx); 1271 } 1272 } else { 1273 // Secure Mode 1274 // We will do QCAMERA_NOTIFY_CALLBACK and share FD in case of secure mode 1275 QCameraMemory *previewMemObj = (QCameraMemory *)frame->mem_info; 1276 if (NULL == previewMemObj) { 1277 LOGE("previewMemObj is NULL"); 1278 stream->bufDone(frame->buf_idx); 1279 goto end; 1280 } 1281 1282 int fd = previewMemObj->getFd(frame->buf_idx); 1283 LOGD("Preview frame fd =%d for index = %d ", fd, frame->buf_idx); 1284 if (pme->needProcessPreviewFrame(frame->frame_idx) && 1285 pme->mDataCb != NULL && 1286 pme->msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_FRAME) > 0) { 1287 // Prepare Callback structure 1288 qcamera_callback_argm_t cbArg; 1289 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 1290 cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK; 1291 cbArg.msg_type = CAMERA_MSG_PREVIEW_FRAME; 1292 #ifndef VANILLA_HAL 1293 cbArg.ext1 = CAMERA_FRAME_DATA_FD; 1294 cbArg.ext2 = fd; 1295 #endif 1296 cbArg.user_data = (void *) &frame->buf_idx; 1297 cbArg.cookie = stream; 1298 cbArg.release_cb = returnStreamBuffer; 1299 // Preset cache flags to be handled when the buffer comes back 1300 frame->cache_flags |= CPU_HAS_READ; 1301 pme->m_cbNotifier.notifyCallback(cbArg); 1302 } else { 1303 LOGH("No need to process preview frame, return buffer"); 1304 stream->bufDone(frame->buf_idx); 1305 } 1306 } 1307 end: 1308 free(super_frame); 1309 LOGH("RDI_DEBUG Exit"); 1310 return; 1311 } 1312 1313 /*=========================================================================== 1314 * FUNCTION : postview_stream_cb_routine 1315 * 1316 * DESCRIPTION: helper function to handle post frame from postview stream 1317 * 1318 * PARAMETERS : 1319 * @super_frame : received super buffer 1320 * @stream : stream object 1321 * @userdata : user data ptr 1322 * 1323 * RETURN : None 1324 * 1325 * NOTE : caller passes the ownership of super_frame, it's our 1326 * responsibility to free super_frame once it's done. 1327 *==========================================================================*/ 1328 void QCamera2HardwareInterface::postview_stream_cb_routine(mm_camera_super_buf_t *super_frame, 1329 QCameraStream *stream, 1330 void *userdata) 1331 { 1332 ATRACE_CALL(); 1333 int err = NO_ERROR; 1334 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 1335 QCameraGrallocMemory *memory = (QCameraGrallocMemory *)super_frame->bufs[0]->mem_info; 1336 1337 if (pme == NULL) { 1338 LOGE("Invalid hardware object"); 1339 free(super_frame); 1340 return; 1341 } 1342 if (memory == NULL) { 1343 LOGE("Invalid memory object"); 1344 free(super_frame); 1345 return; 1346 } 1347 1348 LOGH("[KPI Perf] : BEGIN"); 1349 1350 mm_camera_buf_def_t *frame = super_frame->bufs[0]; 1351 if (NULL == frame) { 1352 LOGE("preview frame is NULL"); 1353 free(super_frame); 1354 return; 1355 } 1356 1357 QCameraMemory *memObj = (QCameraMemory *)frame->mem_info; 1358 if (NULL != memObj) { 1359 pme->dumpFrameToFile(stream, frame, QCAMERA_DUMP_FRM_THUMBNAIL); 1360 } 1361 1362 // Return buffer back to driver 1363 err = stream->bufDone(frame->buf_idx); 1364 if ( err < 0) { 1365 LOGE("stream bufDone failed %d", err); 1366 } 1367 1368 free(super_frame); 1369 LOGH("[KPI Perf] : END"); 1370 return; 1371 } 1372 1373 /*=========================================================================== 1374 * FUNCTION : video_stream_cb_routine 1375 * 1376 * DESCRIPTION: helper function to handle video frame from video stream 1377 * 1378 * PARAMETERS : 1379 * @super_frame : received super buffer 1380 * @stream : stream object 1381 * @userdata : user data ptr 1382 * 1383 * RETURN : None 1384 * 1385 * NOTE : caller passes the ownership of super_frame, it's our 1386 * responsibility to free super_frame once it's done. video 1387 * frame will be sent to video encoder. Once video encoder is 1388 * done with the video frame, it will call another API 1389 * (release_recording_frame) to return the frame back 1390 *==========================================================================*/ 1391 void QCamera2HardwareInterface::video_stream_cb_routine(mm_camera_super_buf_t *super_frame, 1392 QCameraStream *stream, 1393 void *userdata) 1394 { 1395 ATRACE_CALL(); 1396 QCameraVideoMemory *videoMemObj = NULL; 1397 camera_memory_t *video_mem = NULL; 1398 nsecs_t timeStamp = 0; 1399 bool triggerTCB = FALSE; 1400 1401 LOGH("[KPI Perf] : BEGIN"); 1402 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 1403 if (pme == NULL || 1404 pme->mCameraHandle == NULL || 1405 pme->mCameraHandle->camera_handle != super_frame->camera_handle){ 1406 LOGE("camera obj not valid"); 1407 // simply free super frame 1408 free(super_frame); 1409 return; 1410 } 1411 1412 mm_camera_buf_def_t *frame = super_frame->bufs[0]; 1413 1414 if (pme->needDebugFps()) { 1415 pme->debugShowVideoFPS(); 1416 } 1417 if(pme->m_bRecordStarted) { 1418 LOGI("[KPI Perf] : PROFILE_FIRST_RECORD_FRAME"); 1419 pme->m_bRecordStarted = false ; 1420 } 1421 LOGD("Stream(%d), Timestamp: %ld %ld", 1422 frame->stream_id, 1423 frame->ts.tv_sec, 1424 frame->ts.tv_nsec); 1425 1426 if (frame->buf_type == CAM_STREAM_BUF_TYPE_MPLANE) { 1427 if (pme->mParameters.getVideoBatchSize() == 0) { 1428 timeStamp = nsecs_t(frame->ts.tv_sec) * 1000000000LL 1429 + frame->ts.tv_nsec; 1430 LOGD("Video frame to encoder TimeStamp : %lld batch = 0", 1431 timeStamp); 1432 pme->dumpFrameToFile(stream, frame, QCAMERA_DUMP_FRM_VIDEO); 1433 videoMemObj = (QCameraVideoMemory *)frame->mem_info; 1434 video_mem = NULL; 1435 if (NULL != videoMemObj) { 1436 video_mem = videoMemObj->getMemory(frame->buf_idx, 1437 (pme->mStoreMetaDataInFrame > 0)? true : false); 1438 videoMemObj->updateNativeHandle(frame->buf_idx); 1439 triggerTCB = TRUE; 1440 } 1441 } else { 1442 //Handle video batch callback 1443 native_handle_t *nh = NULL; 1444 pme->dumpFrameToFile(stream, frame, QCAMERA_DUMP_FRM_VIDEO); 1445 QCameraVideoMemory *videoMemObj = (QCameraVideoMemory *)frame->mem_info; 1446 if ((stream->mCurMetaMemory == NULL) 1447 || (stream->mCurBufIndex == -1)) { 1448 //get Free metadata available 1449 for (int i = 0; i < CAMERA_MIN_VIDEO_BATCH_BUFFERS; i++) { 1450 if (stream->mStreamMetaMemory[i].consumerOwned == 0) { 1451 stream->mCurMetaMemory = videoMemObj->getMemory(i,true); 1452 stream->mCurBufIndex = 0; 1453 stream->mCurMetaIndex = i; 1454 stream->mStreamMetaMemory[i].numBuffers = 0; 1455 break; 1456 } 1457 } 1458 } 1459 video_mem = stream->mCurMetaMemory; 1460 nh = videoMemObj->updateNativeHandle(stream->mCurMetaIndex); 1461 if (video_mem == NULL || nh == NULL) { 1462 LOGE("No Free metadata. Drop this frame"); 1463 stream->mCurBufIndex = -1; 1464 stream->bufDone(frame->buf_idx); 1465 free(super_frame); 1466 return; 1467 } 1468 1469 int index = stream->mCurBufIndex; 1470 int fd_cnt = pme->mParameters.getVideoBatchSize(); 1471 nsecs_t frame_ts = nsecs_t(frame->ts.tv_sec) * 1000000000LL 1472 + frame->ts.tv_nsec; 1473 if (index == 0) { 1474 stream->mFirstTimeStamp = frame_ts; 1475 } 1476 1477 stream->mStreamMetaMemory[stream->mCurMetaIndex].buf_index[index] 1478 = (uint8_t)frame->buf_idx; 1479 stream->mStreamMetaMemory[stream->mCurMetaIndex].numBuffers++; 1480 stream->mStreamMetaMemory[stream->mCurMetaIndex].consumerOwned 1481 = TRUE; 1482 /* 1483 * data[0] => FD 1484 * data[mNumFDs + 1] => OFFSET 1485 * data[mNumFDs + 2] => SIZE 1486 * data[mNumFDs + 3] => Usage Flag (Color format/Compression) 1487 * data[mNumFDs + 4] => TIMESTAMP 1488 * data[mNumFDs + 5] => FORMAT 1489 */ 1490 nh->data[index] = videoMemObj->getFd(frame->buf_idx); 1491 nh->data[index + fd_cnt] = 0; 1492 nh->data[index + (fd_cnt * 2)] = (int)videoMemObj->getSize(frame->buf_idx); 1493 nh->data[index + (fd_cnt * 3)] = videoMemObj->getUsage(); 1494 nh->data[index + (fd_cnt * 4)] = (int)(frame_ts - stream->mFirstTimeStamp); 1495 nh->data[index + (fd_cnt * 5)] = videoMemObj->getFormat(); 1496 stream->mCurBufIndex++; 1497 if (stream->mCurBufIndex == fd_cnt) { 1498 timeStamp = stream->mFirstTimeStamp; 1499 LOGD("Video frame to encoder TimeStamp : %lld batch = %d", 1500 timeStamp, fd_cnt); 1501 stream->mCurBufIndex = -1; 1502 stream->mCurMetaIndex = -1; 1503 stream->mCurMetaMemory = NULL; 1504 triggerTCB = TRUE; 1505 } 1506 } 1507 } else { 1508 videoMemObj = (QCameraVideoMemory *)frame->mem_info; 1509 video_mem = NULL; 1510 native_handle_t *nh = NULL; 1511 int fd_cnt = frame->user_buf.bufs_used; 1512 if (NULL != videoMemObj) { 1513 video_mem = videoMemObj->getMemory(frame->buf_idx, true); 1514 nh = videoMemObj->updateNativeHandle(frame->buf_idx); 1515 } else { 1516 LOGE("videoMemObj NULL"); 1517 } 1518 1519 if (nh != NULL) { 1520 timeStamp = nsecs_t(frame->ts.tv_sec) * 1000000000LL 1521 + frame->ts.tv_nsec; 1522 LOGD("Batch buffer TimeStamp : %lld FD = %d index = %d fd_cnt = %d", 1523 timeStamp, frame->fd, frame->buf_idx, fd_cnt); 1524 1525 for (int i = 0; i < fd_cnt; i++) { 1526 if (frame->user_buf.buf_idx[i] >= 0) { 1527 mm_camera_buf_def_t *plane_frame = 1528 &frame->user_buf.plane_buf[frame->user_buf.buf_idx[i]]; 1529 QCameraVideoMemory *frameobj = 1530 (QCameraVideoMemory *)plane_frame->mem_info; 1531 int usage = frameobj->getUsage(); 1532 nsecs_t frame_ts = nsecs_t(plane_frame->ts.tv_sec) * 1000000000LL 1533 + plane_frame->ts.tv_nsec; 1534 /* 1535 data[0] => FD 1536 data[mNumFDs + 1] => OFFSET 1537 data[mNumFDs + 2] => SIZE 1538 data[mNumFDs + 3] => Usage Flag (Color format/Compression) 1539 data[mNumFDs + 4] => TIMESTAMP 1540 data[mNumFDs + 5] => FORMAT 1541 */ 1542 nh->data[i] = frameobj->getFd(plane_frame->buf_idx); 1543 nh->data[fd_cnt + i] = 0; 1544 nh->data[(2 * fd_cnt) + i] = (int)frameobj->getSize(plane_frame->buf_idx); 1545 nh->data[(3 * fd_cnt) + i] = usage; 1546 nh->data[(4 * fd_cnt) + i] = (int)(frame_ts - timeStamp); 1547 nh->data[(5 * fd_cnt) + i] = frameobj->getFormat(); 1548 LOGD("Send Video frames to services/encoder delta : %lld FD = %d index = %d", 1549 (frame_ts - timeStamp), plane_frame->fd, plane_frame->buf_idx); 1550 pme->dumpFrameToFile(stream, plane_frame, QCAMERA_DUMP_FRM_VIDEO); 1551 } 1552 } 1553 triggerTCB = TRUE; 1554 } else { 1555 LOGE("No Video Meta Available. Return Buffer"); 1556 stream->bufDone(super_frame->bufs[0]->buf_idx); 1557 } 1558 } 1559 1560 if ((NULL != video_mem) && (triggerTCB == TRUE)) { 1561 if ((pme->mDataCbTimestamp != NULL) && 1562 pme->msgTypeEnabledWithLock(CAMERA_MSG_VIDEO_FRAME) > 0) { 1563 qcamera_callback_argm_t cbArg; 1564 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t)); 1565 cbArg.cb_type = QCAMERA_DATA_TIMESTAMP_CALLBACK; 1566 cbArg.msg_type = CAMERA_MSG_VIDEO_FRAME; 1567 cbArg.data = video_mem; 1568 cbArg.timestamp = timeStamp; 1569 int32_t rc = pme->m_cbNotifier.notifyCallback(cbArg); 1570 if (rc != NO_ERROR) { 1571 LOGE("fail sending data notify"); 1572 stream->bufDone(frame->buf_idx); 1573 } 1574 } 1575 } 1576 1577 free(super_frame); 1578 LOGH("[KPI Perf] : END"); 1579 } 1580 1581 /*=========================================================================== 1582 * FUNCTION : snapshot_channel_cb_routine 1583 * 1584 * DESCRIPTION: helper function to handle snapshot frame from snapshot channel 1585 * 1586 * PARAMETERS : 1587 * @super_frame : received super buffer 1588 * @userdata : user data ptr 1589 * 1590 * RETURN : None 1591 * 1592 * NOTE : recvd_frame will be released after this call by caller, so if 1593 * async operation needed for recvd_frame, it's our responsibility 1594 * to save a copy for this variable to be used later. 1595 *==========================================================================*/ 1596 void QCamera2HardwareInterface::snapshot_channel_cb_routine(mm_camera_super_buf_t *super_frame, 1597 void *userdata) 1598 { 1599 ATRACE_CALL(); 1600 char value[PROPERTY_VALUE_MAX]; 1601 QCameraChannel *pChannel = NULL; 1602 1603 LOGH("[KPI Perf]: E"); 1604 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 1605 if (pme == NULL || 1606 pme->mCameraHandle == NULL || 1607 pme->mCameraHandle->camera_handle != super_frame->camera_handle){ 1608 LOGE("camera obj not valid"); 1609 // simply free super frame 1610 free(super_frame); 1611 return; 1612 } 1613 1614 if (pme->isLowPowerMode()) { 1615 pChannel = pme->m_channels[QCAMERA_CH_TYPE_VIDEO]; 1616 } else { 1617 pChannel = pme->m_channels[QCAMERA_CH_TYPE_SNAPSHOT]; 1618 } 1619 1620 if ((pChannel == NULL) || (pChannel->getMyHandle() != super_frame->ch_id)) { 1621 LOGE("Snapshot channel doesn't exist, return here"); 1622 return; 1623 } 1624 1625 property_get("persist.camera.dumpmetadata", value, "0"); 1626 int32_t enabled = atoi(value); 1627 if (enabled) { 1628 if (pChannel == NULL || 1629 pChannel->getMyHandle() != super_frame->ch_id) { 1630 LOGE("Capture channel doesn't exist, return here"); 1631 return; 1632 } 1633 mm_camera_buf_def_t *pMetaFrame = NULL; 1634 QCameraStream *pStream = NULL; 1635 for (uint32_t i = 0; i < super_frame->num_bufs; i++) { 1636 pStream = pChannel->getStreamByHandle(super_frame->bufs[i]->stream_id); 1637 if (pStream != NULL) { 1638 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) { 1639 pMetaFrame = super_frame->bufs[i]; //find the metadata 1640 if (pMetaFrame != NULL && 1641 ((metadata_buffer_t *)pMetaFrame->buffer)->is_tuning_params_valid) { 1642 pme->dumpMetadataToFile(pStream, pMetaFrame, (char *) "Snapshot"); 1643 } 1644 break; 1645 } 1646 } 1647 } 1648 } 1649 1650 // save a copy for the superbuf 1651 mm_camera_super_buf_t* frame = (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t)); 1652 if (frame == NULL) { 1653 LOGE("Error allocating memory to save received_frame structure."); 1654 pChannel->bufDone(super_frame); 1655 return; 1656 } 1657 *frame = *super_frame; 1658 1659 if (frame->num_bufs > 0) { 1660 LOGI("[KPI Perf]: superbuf frame_idx %d", 1661 frame->bufs[0]->frame_idx); 1662 } 1663 1664 if ((NO_ERROR != pme->waitDeferredWork(pme->mReprocJob)) || 1665 (NO_ERROR != pme->m_postprocessor.processData(frame))) { 1666 LOGE("Failed to trigger process data"); 1667 pChannel->bufDone(super_frame); 1668 free(frame); 1669 frame = NULL; 1670 return; 1671 } 1672 1673 LOGH("[KPI Perf]: X"); 1674 } 1675 1676 /*=========================================================================== 1677 * FUNCTION : raw_stream_cb_routine 1678 * 1679 * DESCRIPTION: helper function to handle raw dump frame from raw stream 1680 * 1681 * PARAMETERS : 1682 * @super_frame : received super buffer 1683 * @stream : stream object 1684 * @userdata : user data ptr 1685 * 1686 * RETURN : None 1687 * 1688 * NOTE : caller passes the ownership of super_frame, it's our 1689 * responsibility to free super_frame once it's done. For raw 1690 * frame, there is no need to send to postprocessor for jpeg 1691 * encoding. this function will play shutter and send the data 1692 * callback to upper layer. Raw frame buffer will be returned 1693 * back to kernel, and frame will be free after use. 1694 *==========================================================================*/ 1695 void QCamera2HardwareInterface::raw_stream_cb_routine(mm_camera_super_buf_t * super_frame, 1696 QCameraStream * /*stream*/, 1697 void * userdata) 1698 { 1699 ATRACE_CALL(); 1700 LOGH("[KPI Perf] : BEGIN"); 1701 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 1702 if (pme == NULL || 1703 pme->mCameraHandle == NULL || 1704 pme->mCameraHandle->camera_handle != super_frame->camera_handle){ 1705 LOGE("camera obj not valid"); 1706 // simply free super frame 1707 free(super_frame); 1708 return; 1709 } 1710 1711 pme->m_postprocessor.processRawData(super_frame); 1712 LOGH("[KPI Perf] : END"); 1713 } 1714 1715 /*=========================================================================== 1716 * FUNCTION : raw_channel_cb_routine 1717 * 1718 * DESCRIPTION: helper function to handle RAW superbuf callback directly from 1719 * mm-camera-interface 1720 * 1721 * PARAMETERS : 1722 * @super_frame : received super buffer 1723 * @userdata : user data ptr 1724 * 1725 * RETURN : None 1726 * 1727 * NOTE : recvd_frame will be released after this call by caller, so if 1728 * async operation needed for recvd_frame, it's our responsibility 1729 * to save a copy for this variable to be used later. 1730 *==========================================================================*/ 1731 void QCamera2HardwareInterface::raw_channel_cb_routine(mm_camera_super_buf_t *super_frame, 1732 void *userdata) 1733 1734 { 1735 ATRACE_CALL(); 1736 char value[PROPERTY_VALUE_MAX]; 1737 1738 LOGH("[KPI Perf]: E"); 1739 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 1740 if (pme == NULL || 1741 pme->mCameraHandle == NULL || 1742 pme->mCameraHandle->camera_handle != super_frame->camera_handle){ 1743 LOGE("camera obj not valid"); 1744 // simply free super frame 1745 free(super_frame); 1746 return; 1747 } 1748 1749 QCameraChannel *pChannel = pme->m_channels[QCAMERA_CH_TYPE_RAW]; 1750 if (pChannel == NULL) { 1751 LOGE("RAW channel doesn't exist, return here"); 1752 return; 1753 } 1754 1755 if (pChannel->getMyHandle() != super_frame->ch_id) { 1756 LOGE("Invalid Input super buffer"); 1757 pChannel->bufDone(super_frame); 1758 return; 1759 } 1760 1761 property_get("persist.camera.dumpmetadata", value, "0"); 1762 int32_t enabled = atoi(value); 1763 if (enabled) { 1764 mm_camera_buf_def_t *pMetaFrame = NULL; 1765 QCameraStream *pStream = NULL; 1766 for (uint32_t i = 0; i < super_frame->num_bufs; i++) { 1767 pStream = pChannel->getStreamByHandle(super_frame->bufs[i]->stream_id); 1768 if (pStream != NULL) { 1769 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) { 1770 pMetaFrame = super_frame->bufs[i]; //find the metadata 1771 if (pMetaFrame != NULL && 1772 ((metadata_buffer_t *)pMetaFrame->buffer)->is_tuning_params_valid) { 1773 pme->dumpMetadataToFile(pStream, pMetaFrame, (char *) "raw"); 1774 } 1775 break; 1776 } 1777 } 1778 } 1779 } 1780 1781 // save a copy for the superbuf 1782 mm_camera_super_buf_t* frame = (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t)); 1783 if (frame == NULL) { 1784 LOGE("Error allocating memory to save received_frame structure."); 1785 pChannel->bufDone(super_frame); 1786 return; 1787 } 1788 *frame = *super_frame; 1789 1790 if (frame->num_bufs > 0) { 1791 LOGI("[KPI Perf]: superbuf frame_idx %d", 1792 frame->bufs[0]->frame_idx); 1793 } 1794 1795 // Wait on Postproc initialization if needed 1796 // then send to postprocessor 1797 if ((NO_ERROR != pme->waitDeferredWork(pme->mReprocJob)) || 1798 (NO_ERROR != pme->m_postprocessor.processData(frame))) { 1799 LOGE("Failed to trigger process data"); 1800 pChannel->bufDone(super_frame); 1801 free(frame); 1802 frame = NULL; 1803 return; 1804 } 1805 1806 LOGH("[KPI Perf]: X"); 1807 1808 } 1809 1810 /*=========================================================================== 1811 * FUNCTION : preview_raw_stream_cb_routine 1812 * 1813 * DESCRIPTION: helper function to handle raw frame during standard preview 1814 * 1815 * PARAMETERS : 1816 * @super_frame : received super buffer 1817 * @stream : stream object 1818 * @userdata : user data ptr 1819 * 1820 * RETURN : None 1821 * 1822 * NOTE : caller passes the ownership of super_frame, it's our 1823 * responsibility to free super_frame once it's done. 1824 *==========================================================================*/ 1825 void QCamera2HardwareInterface::preview_raw_stream_cb_routine(mm_camera_super_buf_t * super_frame, 1826 QCameraStream * stream, 1827 void * userdata) 1828 { 1829 ATRACE_CALL(); 1830 LOGH("[KPI Perf] : BEGIN"); 1831 char value[PROPERTY_VALUE_MAX]; 1832 bool dump_preview_raw = false, dump_video_raw = false; 1833 1834 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 1835 if (pme == NULL || 1836 pme->mCameraHandle == NULL || 1837 pme->mCameraHandle->camera_handle != super_frame->camera_handle){ 1838 LOGE("camera obj not valid"); 1839 // simply free super frame 1840 free(super_frame); 1841 return; 1842 } 1843 1844 mm_camera_buf_def_t *raw_frame = super_frame->bufs[0]; 1845 1846 if (raw_frame != NULL) { 1847 property_get("persist.camera.preview_raw", value, "0"); 1848 dump_preview_raw = atoi(value) > 0 ? true : false; 1849 property_get("persist.camera.video_raw", value, "0"); 1850 dump_video_raw = atoi(value) > 0 ? true : false; 1851 if (dump_preview_raw || (pme->mParameters.getRecordingHintValue() 1852 && dump_video_raw)) { 1853 pme->dumpFrameToFile(stream, raw_frame, QCAMERA_DUMP_FRM_RAW); 1854 } 1855 stream->bufDone(raw_frame->buf_idx); 1856 } 1857 free(super_frame); 1858 1859 LOGH("[KPI Perf] : END"); 1860 } 1861 1862 /*=========================================================================== 1863 * FUNCTION : snapshot_raw_stream_cb_routine 1864 * 1865 * DESCRIPTION: helper function to handle raw frame during standard capture 1866 * 1867 * PARAMETERS : 1868 * @super_frame : received super buffer 1869 * @stream : stream object 1870 * @userdata : user data ptr 1871 * 1872 * RETURN : None 1873 * 1874 * NOTE : caller passes the ownership of super_frame, it's our 1875 * responsibility to free super_frame once it's done. 1876 *==========================================================================*/ 1877 void QCamera2HardwareInterface::snapshot_raw_stream_cb_routine(mm_camera_super_buf_t * super_frame, 1878 QCameraStream * stream, 1879 void * userdata) 1880 { 1881 ATRACE_CALL(); 1882 LOGH("[KPI Perf] : BEGIN"); 1883 char value[PROPERTY_VALUE_MAX]; 1884 bool dump_raw = false; 1885 1886 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 1887 if (pme == NULL || 1888 pme->mCameraHandle == NULL || 1889 pme->mCameraHandle->camera_handle != super_frame->camera_handle){ 1890 LOGE("camera obj not valid"); 1891 // simply free super frame 1892 free(super_frame); 1893 return; 1894 } 1895 1896 property_get("persist.camera.snapshot_raw", value, "0"); 1897 dump_raw = atoi(value) > 0 ? true : false; 1898 1899 for (uint32_t i = 0; i < super_frame->num_bufs; i++) { 1900 if (super_frame->bufs[i]->stream_type == CAM_STREAM_TYPE_RAW) { 1901 mm_camera_buf_def_t * raw_frame = super_frame->bufs[i]; 1902 if (NULL != stream) { 1903 if (dump_raw) { 1904 pme->dumpFrameToFile(stream, raw_frame, QCAMERA_DUMP_FRM_RAW); 1905 } 1906 stream->bufDone(super_frame->bufs[i]->buf_idx); 1907 } 1908 break; 1909 } 1910 } 1911 1912 free(super_frame); 1913 1914 LOGH("[KPI Perf] : END"); 1915 } 1916 1917 /*=========================================================================== 1918 * FUNCTION : updateMetadata 1919 * 1920 * DESCRIPTION: Frame related parameter can be updated here 1921 * 1922 * PARAMETERS : 1923 * @pMetaData : pointer to metadata buffer 1924 * 1925 * RETURN : int32_t type of status 1926 * NO_ERROR -- success 1927 * none-zero failure code 1928 *==========================================================================*/ 1929 int32_t QCamera2HardwareInterface::updateMetadata(metadata_buffer_t *pMetaData) 1930 { 1931 int32_t rc = NO_ERROR; 1932 1933 if (pMetaData == NULL) { 1934 LOGE("Null Metadata buffer"); 1935 return rc; 1936 } 1937 1938 // Sharpness 1939 cam_edge_application_t edge_application; 1940 memset(&edge_application, 0x00, sizeof(cam_edge_application_t)); 1941 edge_application.sharpness = mParameters.getSharpness(); 1942 if (edge_application.sharpness != 0) { 1943 edge_application.edge_mode = CAM_EDGE_MODE_FAST; 1944 } else { 1945 edge_application.edge_mode = CAM_EDGE_MODE_OFF; 1946 } 1947 ADD_SET_PARAM_ENTRY_TO_BATCH(pMetaData, 1948 CAM_INTF_META_EDGE_MODE, edge_application); 1949 1950 //Effect 1951 int32_t prmEffect = mParameters.getEffect(); 1952 ADD_SET_PARAM_ENTRY_TO_BATCH(pMetaData, CAM_INTF_PARM_EFFECT, prmEffect); 1953 1954 //flip 1955 int32_t prmFlip = mParameters.getFlipMode(CAM_STREAM_TYPE_SNAPSHOT); 1956 ADD_SET_PARAM_ENTRY_TO_BATCH(pMetaData, CAM_INTF_PARM_FLIP, prmFlip); 1957 1958 //denoise 1959 uint8_t prmDenoise = (uint8_t)mParameters.isWNREnabled(); 1960 ADD_SET_PARAM_ENTRY_TO_BATCH(pMetaData, 1961 CAM_INTF_META_NOISE_REDUCTION_MODE, prmDenoise); 1962 1963 //rotation & device rotation 1964 uint32_t prmRotation = mParameters.getJpegRotation(); 1965 cam_rotation_info_t rotation_info; 1966 memset(&rotation_info, 0, sizeof(cam_rotation_info_t)); 1967 if (prmRotation == 0) { 1968 rotation_info.rotation = ROTATE_0; 1969 } else if (prmRotation == 90) { 1970 rotation_info.rotation = ROTATE_90; 1971 } else if (prmRotation == 180) { 1972 rotation_info.rotation = ROTATE_180; 1973 } else if (prmRotation == 270) { 1974 rotation_info.rotation = ROTATE_270; 1975 } 1976 1977 uint32_t device_rotation = mParameters.getDeviceRotation(); 1978 if (device_rotation == 0) { 1979 rotation_info.device_rotation = ROTATE_0; 1980 } else if (device_rotation == 90) { 1981 rotation_info.device_rotation = ROTATE_90; 1982 } else if (device_rotation == 180) { 1983 rotation_info.device_rotation = ROTATE_180; 1984 } else if (device_rotation == 270) { 1985 rotation_info.device_rotation = ROTATE_270; 1986 } else { 1987 rotation_info.device_rotation = ROTATE_0; 1988 } 1989 1990 ADD_SET_PARAM_ENTRY_TO_BATCH(pMetaData, CAM_INTF_PARM_ROTATION, rotation_info); 1991 1992 // Imglib Dynamic Scene Data 1993 cam_dyn_img_data_t dyn_img_data = mParameters.getDynamicImgData(); 1994 if (mParameters.isStillMoreEnabled()) { 1995 cam_still_more_t stillmore_cap = mParameters.getStillMoreSettings(); 1996 dyn_img_data.input_count = stillmore_cap.burst_count; 1997 } 1998 ADD_SET_PARAM_ENTRY_TO_BATCH(pMetaData, 1999 CAM_INTF_META_IMG_DYN_FEAT, dyn_img_data); 2000 2001 //CPP CDS 2002 int32_t prmCDSMode = mParameters.getCDSMode(); 2003 ADD_SET_PARAM_ENTRY_TO_BATCH(pMetaData, 2004 CAM_INTF_PARM_CDS_MODE, prmCDSMode); 2005 2006 return rc; 2007 } 2008 2009 /*=========================================================================== 2010 * FUNCTION : metadata_stream_cb_routine 2011 * 2012 * DESCRIPTION: helper function to handle metadata frame from metadata stream 2013 * 2014 * PARAMETERS : 2015 * @super_frame : received super buffer 2016 * @stream : stream object 2017 * @userdata : user data ptr 2018 * 2019 * RETURN : None 2020 * 2021 * NOTE : caller passes the ownership of super_frame, it's our 2022 * responsibility to free super_frame once it's done. Metadata 2023 * could have valid entries for face detection result or 2024 * histogram statistics information. 2025 *==========================================================================*/ 2026 void QCamera2HardwareInterface::metadata_stream_cb_routine(mm_camera_super_buf_t * super_frame, 2027 QCameraStream * stream, 2028 void * userdata) 2029 { 2030 ATRACE_CALL(); 2031 LOGD("[KPI Perf] : BEGIN"); 2032 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 2033 if (pme == NULL || 2034 pme->mCameraHandle == NULL || 2035 pme->mCameraHandle->camera_handle != super_frame->camera_handle){ 2036 LOGE("camera obj not valid"); 2037 // simply free super frame 2038 free(super_frame); 2039 return; 2040 } 2041 2042 mm_camera_buf_def_t *frame = super_frame->bufs[0]; 2043 metadata_buffer_t *pMetaData = (metadata_buffer_t *)frame->buffer; 2044 if(pme->m_stateMachine.isNonZSLCaptureRunning()&& 2045 !pme->mLongshotEnabled) { 2046 //Make shutter call back in non ZSL mode once raw frame is received from VFE. 2047 pme->playShutter(); 2048 } 2049 2050 if (pMetaData->is_tuning_params_valid && pme->mParameters.getRecordingHintValue() == true) { 2051 //Dump Tuning data for video 2052 pme->dumpMetadataToFile(stream,frame,(char *)"Video"); 2053 } 2054 2055 IF_META_AVAILABLE(cam_hist_stats_t, stats_data, CAM_INTF_META_HISTOGRAM, pMetaData) { 2056 // process histogram statistics info 2057 qcamera_sm_internal_evt_payload_t *payload = 2058 (qcamera_sm_internal_evt_payload_t *) 2059 malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 2060 if (NULL != payload) { 2061 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 2062 payload->evt_type = QCAMERA_INTERNAL_EVT_HISTOGRAM_STATS; 2063 payload->stats_data = *stats_data; 2064 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 2065 if (rc != NO_ERROR) { 2066 LOGW("processEvt histogram failed"); 2067 free(payload); 2068 payload = NULL; 2069 2070 } 2071 } else { 2072 LOGE("No memory for histogram qcamera_sm_internal_evt_payload_t"); 2073 } 2074 } 2075 2076 IF_META_AVAILABLE(cam_face_detection_data_t, detection_data, 2077 CAM_INTF_META_FACE_DETECTION, pMetaData) { 2078 2079 cam_faces_data_t faces_data; 2080 pme->fillFacesData(faces_data, pMetaData); 2081 faces_data.detection_data.fd_type = QCAMERA_FD_PREVIEW; //HARD CODE here before MCT can support 2082 2083 qcamera_sm_internal_evt_payload_t *payload = (qcamera_sm_internal_evt_payload_t *) 2084 malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 2085 if (NULL != payload) { 2086 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 2087 payload->evt_type = QCAMERA_INTERNAL_EVT_FACE_DETECT_RESULT; 2088 payload->faces_data = faces_data; 2089 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 2090 if (rc != NO_ERROR) { 2091 LOGW("processEvt face detection failed"); 2092 free(payload); 2093 payload = NULL; 2094 } 2095 } else { 2096 LOGE("No memory for face detect qcamera_sm_internal_evt_payload_t"); 2097 } 2098 } 2099 2100 IF_META_AVAILABLE(uint32_t, afState, CAM_INTF_META_AF_STATE, pMetaData) { 2101 uint8_t forceAFUpdate = FALSE; 2102 //1. Earlier HAL used to rely on AF done flags set in metadata to generate callbacks to 2103 //upper layers. But in scenarios where metadata drops especially which contain important 2104 //AF information, APP will wait indefinitely for focus result resulting in capture hang. 2105 //2. HAL can check for AF state transitions to generate AF state callbacks to upper layers. 2106 //This will help overcome metadata drop issue with the earlier approach. 2107 //3. But sometimes AF state transitions can happen so fast within same metadata due to 2108 //which HAL will receive only the final AF state. HAL may perceive this as no change in AF 2109 //state depending on the state transitions happened (for example state A -> B -> A). 2110 //4. To overcome the drawbacks of both the approaches, we go for a hybrid model in which 2111 //we check state transition at both HAL level and AF module level. We rely on 2112 //'state transition' meta field set by AF module for the state transition detected by it. 2113 IF_META_AVAILABLE(uint8_t, stateChange, CAM_INTF_AF_STATE_TRANSITION, pMetaData) { 2114 forceAFUpdate = *stateChange; 2115 } 2116 //This is a special scenario in which when scene modes like landscape are selected, AF mode 2117 //gets changed to INFINITY at backend, but HAL will not be aware of it. Also, AF state in 2118 //such cases will be set to CAM_AF_STATE_INACTIVE by backend. So, detect the AF mode 2119 //change here and trigger AF callback @ processAutoFocusEvent(). 2120 IF_META_AVAILABLE(uint32_t, afFocusMode, CAM_INTF_PARM_FOCUS_MODE, pMetaData) { 2121 if (((cam_focus_mode_type)(*afFocusMode) == CAM_FOCUS_MODE_INFINITY) && 2122 pme->mActiveAF){ 2123 forceAFUpdate = TRUE; 2124 } 2125 } 2126 if ((pme->m_currentFocusState != (*afState)) || forceAFUpdate) { 2127 cam_af_state_t prevFocusState = pme->m_currentFocusState; 2128 pme->m_currentFocusState = (cam_af_state_t)(*afState); 2129 qcamera_sm_internal_evt_payload_t *payload = (qcamera_sm_internal_evt_payload_t *) 2130 malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 2131 if (NULL != payload) { 2132 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 2133 payload->evt_type = QCAMERA_INTERNAL_EVT_FOCUS_UPDATE; 2134 payload->focus_data.focus_state = (cam_af_state_t)(*afState); 2135 //Need to flush ZSL Q only if we are transitioning from scanning state 2136 //to focused/not focused state. 2137 payload->focus_data.flush_info.needFlush = 2138 ((prevFocusState == CAM_AF_STATE_PASSIVE_SCAN) || 2139 (prevFocusState == CAM_AF_STATE_ACTIVE_SCAN)) && 2140 ((pme->m_currentFocusState == CAM_AF_STATE_FOCUSED_LOCKED) || 2141 (pme->m_currentFocusState == CAM_AF_STATE_NOT_FOCUSED_LOCKED)); 2142 payload->focus_data.flush_info.focused_frame_idx = frame->frame_idx; 2143 2144 IF_META_AVAILABLE(float, focusDistance, 2145 CAM_INTF_META_LENS_FOCUS_DISTANCE, pMetaData) { 2146 payload->focus_data.focus_dist. 2147 focus_distance[CAM_FOCUS_DISTANCE_OPTIMAL_INDEX] = *focusDistance; 2148 } 2149 IF_META_AVAILABLE(float, focusRange, CAM_INTF_META_LENS_FOCUS_RANGE, pMetaData) { 2150 payload->focus_data.focus_dist. 2151 focus_distance[CAM_FOCUS_DISTANCE_NEAR_INDEX] = focusRange[0]; 2152 payload->focus_data.focus_dist. 2153 focus_distance[CAM_FOCUS_DISTANCE_FAR_INDEX] = focusRange[1]; 2154 } 2155 IF_META_AVAILABLE(uint32_t, focusMode, CAM_INTF_PARM_FOCUS_MODE, pMetaData) { 2156 payload->focus_data.focus_mode = (cam_focus_mode_type)(*focusMode); 2157 } 2158 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 2159 if (rc != NO_ERROR) { 2160 LOGW("processEvt focus failed"); 2161 free(payload); 2162 payload = NULL; 2163 } 2164 } else { 2165 LOGE("No memory for focus qcamera_sm_internal_evt_payload_t"); 2166 } 2167 } 2168 } 2169 2170 IF_META_AVAILABLE(cam_crop_data_t, crop_data, CAM_INTF_META_CROP_DATA, pMetaData) { 2171 if (crop_data->num_of_streams > MAX_NUM_STREAMS) { 2172 LOGE("Invalid num_of_streams %d in crop_data", 2173 crop_data->num_of_streams); 2174 } else { 2175 qcamera_sm_internal_evt_payload_t *payload = 2176 (qcamera_sm_internal_evt_payload_t *) 2177 malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 2178 if (NULL != payload) { 2179 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 2180 payload->evt_type = QCAMERA_INTERNAL_EVT_CROP_INFO; 2181 payload->crop_data = *crop_data; 2182 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 2183 if (rc != NO_ERROR) { 2184 LOGE("processEvt crop info failed"); 2185 free(payload); 2186 payload = NULL; 2187 } 2188 } else { 2189 LOGE("No memory for prep_snapshot qcamera_sm_internal_evt_payload_t"); 2190 } 2191 } 2192 } 2193 2194 IF_META_AVAILABLE(int32_t, prep_snapshot_done_state, 2195 CAM_INTF_META_PREP_SNAPSHOT_DONE, pMetaData) { 2196 qcamera_sm_internal_evt_payload_t *payload = 2197 (qcamera_sm_internal_evt_payload_t *)malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 2198 if (NULL != payload) { 2199 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 2200 payload->evt_type = QCAMERA_INTERNAL_EVT_PREP_SNAPSHOT_DONE; 2201 payload->prep_snapshot_state = (cam_prep_snapshot_state_t)*prep_snapshot_done_state; 2202 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 2203 if (rc != NO_ERROR) { 2204 LOGW("processEvt prep_snapshot failed"); 2205 free(payload); 2206 payload = NULL; 2207 } 2208 } else { 2209 LOGE("No memory for prep_snapshot qcamera_sm_internal_evt_payload_t"); 2210 } 2211 } 2212 2213 IF_META_AVAILABLE(cam_asd_hdr_scene_data_t, hdr_scene_data, 2214 CAM_INTF_META_ASD_HDR_SCENE_DATA, pMetaData) { 2215 LOGH("hdr_scene_data: %d %f\n", 2216 hdr_scene_data->is_hdr_scene, hdr_scene_data->hdr_confidence); 2217 //Handle this HDR meta data only if capture is not in process 2218 if (!pme->m_stateMachine.isCaptureRunning()) { 2219 qcamera_sm_internal_evt_payload_t *payload = 2220 (qcamera_sm_internal_evt_payload_t *) 2221 malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 2222 if (NULL != payload) { 2223 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 2224 payload->evt_type = QCAMERA_INTERNAL_EVT_HDR_UPDATE; 2225 payload->hdr_data = *hdr_scene_data; 2226 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 2227 if (rc != NO_ERROR) { 2228 LOGW("processEvt hdr update failed"); 2229 free(payload); 2230 payload = NULL; 2231 } 2232 } else { 2233 LOGE("No memory for hdr update qcamera_sm_internal_evt_payload_t"); 2234 } 2235 } 2236 } 2237 2238 IF_META_AVAILABLE(cam_asd_decision_t, cam_asd_info, 2239 CAM_INTF_META_ASD_SCENE_INFO, pMetaData) { 2240 qcamera_sm_internal_evt_payload_t *payload = 2241 (qcamera_sm_internal_evt_payload_t *)malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 2242 if (NULL != payload) { 2243 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 2244 payload->evt_type = QCAMERA_INTERNAL_EVT_ASD_UPDATE; 2245 payload->asd_data = (cam_asd_decision_t)*cam_asd_info; 2246 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 2247 if (rc != NO_ERROR) { 2248 LOGW("processEvt asd_update failed"); 2249 free(payload); 2250 payload = NULL; 2251 } 2252 } else { 2253 LOGE("No memory for asd_update qcamera_sm_internal_evt_payload_t"); 2254 } 2255 } 2256 2257 IF_META_AVAILABLE(cam_awb_params_t, awb_params, CAM_INTF_META_AWB_INFO, pMetaData) { 2258 LOGH(", metadata for awb params."); 2259 qcamera_sm_internal_evt_payload_t *payload = 2260 (qcamera_sm_internal_evt_payload_t *) 2261 malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 2262 if (NULL != payload) { 2263 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 2264 payload->evt_type = QCAMERA_INTERNAL_EVT_AWB_UPDATE; 2265 payload->awb_data = *awb_params; 2266 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 2267 if (rc != NO_ERROR) { 2268 LOGW("processEvt awb_update failed"); 2269 free(payload); 2270 payload = NULL; 2271 } 2272 } else { 2273 LOGE("No memory for awb_update qcamera_sm_internal_evt_payload_t"); 2274 } 2275 } 2276 2277 IF_META_AVAILABLE(uint32_t, flash_mode, CAM_INTF_META_FLASH_MODE, pMetaData) { 2278 pme->mExifParams.sensor_params.flash_mode = (cam_flash_mode_t)*flash_mode; 2279 } 2280 2281 IF_META_AVAILABLE(int32_t, flash_state, CAM_INTF_META_FLASH_STATE, pMetaData) { 2282 pme->mExifParams.sensor_params.flash_state = (cam_flash_state_t) *flash_state; 2283 } 2284 2285 IF_META_AVAILABLE(float, aperture_value, CAM_INTF_META_LENS_APERTURE, pMetaData) { 2286 pme->mExifParams.sensor_params.aperture_value = *aperture_value; 2287 } 2288 2289 IF_META_AVAILABLE(cam_3a_params_t, ae_params, CAM_INTF_META_AEC_INFO, pMetaData) { 2290 pme->mExifParams.cam_3a_params = *ae_params; 2291 pme->mExifParams.cam_3a_params_valid = TRUE; 2292 pme->mFlashNeeded = ae_params->flash_needed; 2293 pme->mExifParams.cam_3a_params.brightness = (float) pme->mParameters.getBrightness(); 2294 qcamera_sm_internal_evt_payload_t *payload = 2295 (qcamera_sm_internal_evt_payload_t *) 2296 malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 2297 if (NULL != payload) { 2298 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 2299 payload->evt_type = QCAMERA_INTERNAL_EVT_AE_UPDATE; 2300 payload->ae_data = *ae_params; 2301 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 2302 if (rc != NO_ERROR) { 2303 LOGW("processEvt ae_update failed"); 2304 free(payload); 2305 payload = NULL; 2306 } 2307 } else { 2308 LOGE("No memory for ae_update qcamera_sm_internal_evt_payload_t"); 2309 } 2310 } 2311 2312 IF_META_AVAILABLE(int32_t, wb_mode, CAM_INTF_PARM_WHITE_BALANCE, pMetaData) { 2313 pme->mExifParams.cam_3a_params.wb_mode = (cam_wb_mode_type) *wb_mode; 2314 } 2315 2316 IF_META_AVAILABLE(cam_sensor_params_t, sensor_params, CAM_INTF_META_SENSOR_INFO, pMetaData) { 2317 pme->mExifParams.sensor_params = *sensor_params; 2318 } 2319 2320 IF_META_AVAILABLE(cam_ae_exif_debug_t, ae_exif_debug_params, 2321 CAM_INTF_META_EXIF_DEBUG_AE, pMetaData) { 2322 if (pme->mExifParams.debug_params) { 2323 pme->mExifParams.debug_params->ae_debug_params = *ae_exif_debug_params; 2324 pme->mExifParams.debug_params->ae_debug_params_valid = TRUE; 2325 } 2326 } 2327 2328 IF_META_AVAILABLE(cam_awb_exif_debug_t, awb_exif_debug_params, 2329 CAM_INTF_META_EXIF_DEBUG_AWB, pMetaData) { 2330 if (pme->mExifParams.debug_params) { 2331 pme->mExifParams.debug_params->awb_debug_params = *awb_exif_debug_params; 2332 pme->mExifParams.debug_params->awb_debug_params_valid = TRUE; 2333 } 2334 } 2335 2336 IF_META_AVAILABLE(cam_af_exif_debug_t, af_exif_debug_params, 2337 CAM_INTF_META_EXIF_DEBUG_AF, pMetaData) { 2338 if (pme->mExifParams.debug_params) { 2339 pme->mExifParams.debug_params->af_debug_params = *af_exif_debug_params; 2340 pme->mExifParams.debug_params->af_debug_params_valid = TRUE; 2341 } 2342 } 2343 2344 IF_META_AVAILABLE(cam_asd_exif_debug_t, asd_exif_debug_params, 2345 CAM_INTF_META_EXIF_DEBUG_ASD, pMetaData) { 2346 if (pme->mExifParams.debug_params) { 2347 pme->mExifParams.debug_params->asd_debug_params = *asd_exif_debug_params; 2348 pme->mExifParams.debug_params->asd_debug_params_valid = TRUE; 2349 } 2350 } 2351 2352 IF_META_AVAILABLE(cam_stats_buffer_exif_debug_t, stats_exif_debug_params, 2353 CAM_INTF_META_EXIF_DEBUG_STATS, pMetaData) { 2354 if (pme->mExifParams.debug_params) { 2355 pme->mExifParams.debug_params->stats_debug_params = *stats_exif_debug_params; 2356 pme->mExifParams.debug_params->stats_debug_params_valid = TRUE; 2357 } 2358 } 2359 2360 IF_META_AVAILABLE(cam_bestats_buffer_exif_debug_t, bestats_exif_debug_params, 2361 CAM_INTF_META_EXIF_DEBUG_BESTATS, pMetaData) { 2362 if (pme->mExifParams.debug_params) { 2363 pme->mExifParams.debug_params->bestats_debug_params = *bestats_exif_debug_params; 2364 pme->mExifParams.debug_params->bestats_debug_params_valid = TRUE; 2365 } 2366 } 2367 2368 IF_META_AVAILABLE(cam_bhist_buffer_exif_debug_t, bhist_exif_debug_params, 2369 CAM_INTF_META_EXIF_DEBUG_BHIST, pMetaData) { 2370 if (pme->mExifParams.debug_params) { 2371 pme->mExifParams.debug_params->bhist_debug_params = *bhist_exif_debug_params; 2372 pme->mExifParams.debug_params->bhist_debug_params_valid = TRUE; 2373 } 2374 } 2375 2376 IF_META_AVAILABLE(cam_q3a_tuning_info_t, q3a_tuning_exif_debug_params, 2377 CAM_INTF_META_EXIF_DEBUG_3A_TUNING, pMetaData) { 2378 if (pme->mExifParams.debug_params) { 2379 pme->mExifParams.debug_params->q3a_tuning_debug_params = *q3a_tuning_exif_debug_params; 2380 pme->mExifParams.debug_params->q3a_tuning_debug_params_valid = TRUE; 2381 } 2382 } 2383 2384 IF_META_AVAILABLE(uint32_t, led_mode, CAM_INTF_META_LED_MODE_OVERRIDE, pMetaData) { 2385 qcamera_sm_internal_evt_payload_t *payload = 2386 (qcamera_sm_internal_evt_payload_t *) 2387 malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 2388 if (NULL != payload) { 2389 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 2390 payload->evt_type = QCAMERA_INTERNAL_EVT_LED_MODE_OVERRIDE; 2391 payload->led_data = (cam_flash_mode_t)*led_mode; 2392 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 2393 if (rc != NO_ERROR) { 2394 LOGW("processEvt led mode override failed"); 2395 free(payload); 2396 payload = NULL; 2397 } 2398 } else { 2399 LOGE("No memory for focus qcamera_sm_internal_evt_payload_t"); 2400 } 2401 } 2402 2403 cam_edge_application_t edge_application; 2404 memset(&edge_application, 0x00, sizeof(cam_edge_application_t)); 2405 edge_application.sharpness = pme->mParameters.getSharpness(); 2406 if (edge_application.sharpness != 0) { 2407 edge_application.edge_mode = CAM_EDGE_MODE_FAST; 2408 } else { 2409 edge_application.edge_mode = CAM_EDGE_MODE_OFF; 2410 } 2411 ADD_SET_PARAM_ENTRY_TO_BATCH(pMetaData, CAM_INTF_META_EDGE_MODE, edge_application); 2412 2413 IF_META_AVAILABLE(cam_focus_pos_info_t, cur_pos_info, 2414 CAM_INTF_META_FOCUS_POSITION, pMetaData) { 2415 qcamera_sm_internal_evt_payload_t *payload = 2416 (qcamera_sm_internal_evt_payload_t *)malloc(sizeof(qcamera_sm_internal_evt_payload_t)); 2417 if (NULL != payload) { 2418 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t)); 2419 payload->evt_type = QCAMERA_INTERNAL_EVT_FOCUS_POS_UPDATE; 2420 payload->focus_pos = *cur_pos_info; 2421 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload); 2422 if (rc != NO_ERROR) { 2423 LOGW("processEvt focus_pos_update failed"); 2424 free(payload); 2425 payload = NULL; 2426 } 2427 } else { 2428 LOGE("No memory for focus_pos_update qcamera_sm_internal_evt_payload_t"); 2429 } 2430 } 2431 2432 if (pme->mParameters.getLowLightCapture()) { 2433 IF_META_AVAILABLE(cam_low_light_mode_t, low_light_level, 2434 CAM_INTF_META_LOW_LIGHT, pMetaData) { 2435 pme->mParameters.setLowLightLevel(*low_light_level); 2436 } 2437 } 2438 2439 IF_META_AVAILABLE(cam_dyn_img_data_t, dyn_img_data, 2440 CAM_INTF_META_IMG_DYN_FEAT, pMetaData) { 2441 pme->mParameters.setDynamicImgData(*dyn_img_data); 2442 } 2443 2444 IF_META_AVAILABLE(int32_t, touch_ae_status, CAM_INTF_META_TOUCH_AE_RESULT, pMetaData) { 2445 LOGD("touch_ae_status: %d", *touch_ae_status); 2446 } 2447 2448 stream->bufDone(frame->buf_idx); 2449 free(super_frame); 2450 2451 LOGD("[KPI Perf] : END"); 2452 } 2453 2454 /*=========================================================================== 2455 * FUNCTION : reprocess_stream_cb_routine 2456 * 2457 * DESCRIPTION: helper function to handle reprocess frame from reprocess stream 2458 (after reprocess, e.g., ZSL snapshot frame after WNR if 2459 * WNR is enabled) 2460 * 2461 * PARAMETERS : 2462 * @super_frame : received super buffer 2463 * @stream : stream object 2464 * @userdata : user data ptr 2465 * 2466 * RETURN : None 2467 * 2468 * NOTE : caller passes the ownership of super_frame, it's our 2469 * responsibility to free super_frame once it's done. In this 2470 * case, reprocessed frame need to be passed to postprocessor 2471 * for jpeg encoding. 2472 *==========================================================================*/ 2473 void QCamera2HardwareInterface::reprocess_stream_cb_routine(mm_camera_super_buf_t * super_frame, 2474 QCameraStream * /*stream*/, 2475 void * userdata) 2476 { 2477 ATRACE_CALL(); 2478 LOGH("[KPI Perf]: E"); 2479 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 2480 if (pme == NULL || 2481 pme->mCameraHandle == NULL || 2482 pme->mCameraHandle->camera_handle != super_frame->camera_handle){ 2483 LOGE("camera obj not valid"); 2484 // simply free super frame 2485 free(super_frame); 2486 return; 2487 } 2488 2489 pme->m_postprocessor.processPPData(super_frame); 2490 2491 LOGH("[KPI Perf]: X"); 2492 } 2493 2494 /*=========================================================================== 2495 * FUNCTION : callback_stream_cb_routine 2496 * 2497 * DESCRIPTION: function to process CALBACK stream data 2498 Frame will processed and sent to framework 2499 * 2500 * PARAMETERS : 2501 * @super_frame : received super buffer 2502 * @stream : stream object 2503 * @userdata : user data ptr 2504 * 2505 * RETURN : None 2506 *==========================================================================*/ 2507 void QCamera2HardwareInterface::callback_stream_cb_routine(mm_camera_super_buf_t *super_frame, 2508 QCameraStream *stream, void *userdata) 2509 { 2510 ATRACE_CALL(); 2511 LOGH("[KPI Perf]: E"); 2512 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata; 2513 2514 if (pme == NULL || 2515 pme->mCameraHandle == NULL || 2516 pme->mCameraHandle->camera_handle != super_frame->camera_handle) { 2517 LOGE("camera obj not valid"); 2518 // simply free super frame 2519 free(super_frame); 2520 return; 2521 } 2522 2523 mm_camera_buf_def_t *frame = super_frame->bufs[0]; 2524 if (NULL == frame) { 2525 LOGE("preview callback frame is NULL"); 2526 free(super_frame); 2527 return; 2528 } 2529 2530 if (!pme->needProcessPreviewFrame(frame->frame_idx)) { 2531 LOGH("preview is not running, no need to process"); 2532 stream->bufDone(frame->buf_idx); 2533 free(super_frame); 2534 return; 2535 } 2536 2537 QCameraMemory *previewMemObj = (QCameraMemory *)frame->mem_info; 2538 // Handle preview data callback 2539 if (pme->mDataCb != NULL && 2540 (pme->msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_FRAME) > 0) && 2541 (!pme->mParameters.isSceneSelectionEnabled())) { 2542 // Preset cache flags to be handled when the buffer comes back 2543 frame->cache_flags |= CPU_HAS_READ; 2544 int32_t rc = pme->sendPreviewCallback(stream, previewMemObj, frame->buf_idx); 2545 if (NO_ERROR != rc) { 2546 LOGE("Preview callback was not sent succesfully"); 2547 } 2548 } 2549 stream->bufDone(frame->buf_idx); 2550 free(super_frame); 2551 LOGH("[KPI Perf]: X"); 2552 } 2553 2554 /*=========================================================================== 2555 * FUNCTION : dumpFrameToFile 2556 * 2557 * DESCRIPTION: helper function to dump jpeg into file for debug purpose. 2558 * 2559 * PARAMETERS : 2560 * @data : data ptr 2561 * @size : length of data buffer 2562 * @index : identifier for data 2563 * 2564 * RETURN : None 2565 *==========================================================================*/ 2566 void QCamera2HardwareInterface::dumpJpegToFile(const void *data, 2567 size_t size, uint32_t index) 2568 { 2569 char value[PROPERTY_VALUE_MAX]; 2570 property_get("persist.camera.dumpimg", value, "0"); 2571 uint32_t enabled = (uint32_t) atoi(value); 2572 uint32_t frm_num = 0; 2573 uint32_t skip_mode = 0; 2574 2575 char buf[32]; 2576 cam_dimension_t dim; 2577 memset(buf, 0, sizeof(buf)); 2578 memset(&dim, 0, sizeof(dim)); 2579 2580 if(((enabled & QCAMERA_DUMP_FRM_JPEG) && data) || 2581 ((true == m_bIntJpegEvtPending) && data)) { 2582 frm_num = ((enabled & 0xffff0000) >> 16); 2583 if(frm_num == 0) { 2584 frm_num = 10; //default 10 frames 2585 } 2586 if(frm_num > 256) { 2587 frm_num = 256; //256 buffers cycle around 2588 } 2589 skip_mode = ((enabled & 0x0000ff00) >> 8); 2590 if(skip_mode == 0) { 2591 skip_mode = 1; //no-skip 2592 } 2593 2594 if( mDumpSkipCnt % skip_mode == 0) { 2595 if((frm_num == 256) && (mDumpFrmCnt >= frm_num)) { 2596 // reset frame count if cycling 2597 mDumpFrmCnt = 0; 2598 } 2599 if (mDumpFrmCnt <= frm_num) { 2600 snprintf(buf, sizeof(buf), QCAMERA_DUMP_FRM_LOCATION "%d_%d.jpg", 2601 mDumpFrmCnt, index); 2602 if (true == m_bIntJpegEvtPending) { 2603 strlcpy(m_BackendFileName, buf, QCAMERA_MAX_FILEPATH_LENGTH); 2604 mBackendFileSize = size; 2605 } 2606 2607 int file_fd = open(buf, O_RDWR | O_CREAT, 0777); 2608 if (file_fd >= 0) { 2609 ssize_t written_len = write(file_fd, data, size); 2610 fchmod(file_fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 2611 LOGH("written number of bytes %zd\n", 2612 written_len); 2613 close(file_fd); 2614 } else { 2615 LOGE("fail to open file for image dumping"); 2616 } 2617 if (false == m_bIntJpegEvtPending) { 2618 mDumpFrmCnt++; 2619 } 2620 } 2621 } 2622 mDumpSkipCnt++; 2623 } 2624 } 2625 2626 2627 void QCamera2HardwareInterface::dumpMetadataToFile(QCameraStream *stream, 2628 mm_camera_buf_def_t *frame,char *type) 2629 { 2630 char value[PROPERTY_VALUE_MAX]; 2631 uint32_t frm_num = 0; 2632 metadata_buffer_t *metadata = (metadata_buffer_t *)frame->buffer; 2633 property_get("persist.camera.dumpmetadata", value, "0"); 2634 uint32_t enabled = (uint32_t) atoi(value); 2635 if (stream == NULL) { 2636 LOGH("No op"); 2637 return; 2638 } 2639 2640 uint32_t dumpFrmCnt = stream->mDumpMetaFrame; 2641 if(enabled){ 2642 frm_num = ((enabled & 0xffff0000) >> 16); 2643 if (frm_num == 0) { 2644 frm_num = 10; //default 10 frames 2645 } 2646 if (frm_num > 256) { 2647 frm_num = 256; //256 buffers cycle around 2648 } 2649 if ((frm_num == 256) && (dumpFrmCnt >= frm_num)) { 2650 // reset frame count if cycling 2651 dumpFrmCnt = 0; 2652 } 2653 LOGH("dumpFrmCnt= %u, frm_num = %u", dumpFrmCnt, frm_num); 2654 if (dumpFrmCnt < frm_num) { 2655 char timeBuf[128]; 2656 char buf[32]; 2657 memset(buf, 0, sizeof(buf)); 2658 memset(timeBuf, 0, sizeof(timeBuf)); 2659 time_t current_time; 2660 struct tm * timeinfo; 2661 time (¤t_time); 2662 timeinfo = localtime (¤t_time); 2663 if (NULL != timeinfo) { 2664 strftime(timeBuf, sizeof(timeBuf), 2665 QCAMERA_DUMP_FRM_LOCATION "%Y%m%d%H%M%S", timeinfo); 2666 } 2667 String8 filePath(timeBuf); 2668 snprintf(buf, sizeof(buf), "%um_%s_%d.bin", dumpFrmCnt, type, frame->frame_idx); 2669 filePath.append(buf); 2670 int file_fd = open(filePath.string(), O_RDWR | O_CREAT, 0777); 2671 if (file_fd >= 0) { 2672 ssize_t written_len = 0; 2673 metadata->tuning_params.tuning_data_version = TUNING_DATA_VERSION; 2674 void *data = (void *)((uint8_t *)&metadata->tuning_params.tuning_data_version); 2675 written_len += write(file_fd, data, sizeof(uint32_t)); 2676 data = (void *)((uint8_t *)&metadata->tuning_params.tuning_sensor_data_size); 2677 LOGH("tuning_sensor_data_size %d",(int)(*(int *)data)); 2678 written_len += write(file_fd, data, sizeof(uint32_t)); 2679 data = (void *)((uint8_t *)&metadata->tuning_params.tuning_vfe_data_size); 2680 LOGH("tuning_vfe_data_size %d",(int)(*(int *)data)); 2681 written_len += write(file_fd, data, sizeof(uint32_t)); 2682 data = (void *)((uint8_t *)&metadata->tuning_params.tuning_cpp_data_size); 2683 LOGH("tuning_cpp_data_size %d",(int)(*(int *)data)); 2684 written_len += write(file_fd, data, sizeof(uint32_t)); 2685 data = (void *)((uint8_t *)&metadata->tuning_params.tuning_cac_data_size); 2686 LOGH("tuning_cac_data_size %d",(int)(*(int *)data)); 2687 written_len += write(file_fd, data, sizeof(uint32_t)); 2688 data = (void *)((uint8_t *)&metadata->tuning_params.tuning_cac_data_size2); 2689 LOGH("< skrajago >tuning_cac_data_size %d",(int)(*(int *)data)); 2690 written_len += write(file_fd, data, sizeof(uint32_t)); 2691 size_t total_size = metadata->tuning_params.tuning_sensor_data_size; 2692 data = (void *)((uint8_t *)&metadata->tuning_params.data); 2693 written_len += write(file_fd, data, total_size); 2694 total_size = metadata->tuning_params.tuning_vfe_data_size; 2695 data = (void *)((uint8_t *)&metadata->tuning_params.data[TUNING_VFE_DATA_OFFSET]); 2696 written_len += write(file_fd, data, total_size); 2697 total_size = metadata->tuning_params.tuning_cpp_data_size; 2698 data = (void *)((uint8_t *)&metadata->tuning_params.data[TUNING_CPP_DATA_OFFSET]); 2699 written_len += write(file_fd, data, total_size); 2700 total_size = metadata->tuning_params.tuning_cac_data_size; 2701 data = (void *)((uint8_t *)&metadata->tuning_params.data[TUNING_CAC_DATA_OFFSET]); 2702 written_len += write(file_fd, data, total_size); 2703 close(file_fd); 2704 }else { 2705 LOGE("fail t open file for image dumping"); 2706 } 2707 dumpFrmCnt++; 2708 } 2709 } 2710 stream->mDumpMetaFrame = dumpFrmCnt; 2711 } 2712 /*=========================================================================== 2713 * FUNCTION : dumpFrameToFile 2714 * 2715 * DESCRIPTION: helper function to dump frame into file for debug purpose. 2716 * 2717 * PARAMETERS : 2718 * @data : data ptr 2719 * @size : length of data buffer 2720 * @index : identifier for data 2721 * @dump_type : type of the frame to be dumped. Only such 2722 * dump type is enabled, the frame will be 2723 * dumped into a file. 2724 * 2725 * RETURN : None 2726 *==========================================================================*/ 2727 void QCamera2HardwareInterface::dumpFrameToFile(QCameraStream *stream, 2728 mm_camera_buf_def_t *frame, uint32_t dump_type, const char *misc) 2729 { 2730 char value[PROPERTY_VALUE_MAX]; 2731 property_get("persist.camera.dumpimg", value, "0"); 2732 uint32_t enabled = (uint32_t) atoi(value); 2733 uint32_t frm_num = 0; 2734 uint32_t skip_mode = 0; 2735 2736 if (NULL == stream) { 2737 LOGE("stream object is null"); 2738 return; 2739 } 2740 2741 uint32_t dumpFrmCnt = stream->mDumpFrame; 2742 2743 if (true == m_bIntRawEvtPending) { 2744 enabled = QCAMERA_DUMP_FRM_RAW; 2745 } 2746 2747 if((enabled & QCAMERA_DUMP_FRM_MASK_ALL)) { 2748 if((enabled & dump_type) && stream && frame) { 2749 frm_num = ((enabled & 0xffff0000) >> 16); 2750 if(frm_num == 0) { 2751 frm_num = 10; //default 10 frames 2752 } 2753 if(frm_num > 256) { 2754 frm_num = 256; //256 buffers cycle around 2755 } 2756 skip_mode = ((enabled & 0x0000ff00) >> 8); 2757 if(skip_mode == 0) { 2758 skip_mode = 1; //no-skip 2759 } 2760 if(stream->mDumpSkipCnt == 0) 2761 stream->mDumpSkipCnt = 1; 2762 2763 if( stream->mDumpSkipCnt % skip_mode == 0) { 2764 if((frm_num == 256) && (dumpFrmCnt >= frm_num)) { 2765 // reset frame count if cycling 2766 dumpFrmCnt = 0; 2767 } 2768 if (dumpFrmCnt <= frm_num) { 2769 char buf[32]; 2770 char timeBuf[128]; 2771 time_t current_time; 2772 struct tm * timeinfo; 2773 2774 memset(timeBuf, 0, sizeof(timeBuf)); 2775 2776 time (¤t_time); 2777 timeinfo = localtime (¤t_time); 2778 memset(buf, 0, sizeof(buf)); 2779 2780 cam_dimension_t dim; 2781 memset(&dim, 0, sizeof(dim)); 2782 stream->getFrameDimension(dim); 2783 2784 cam_frame_len_offset_t offset; 2785 memset(&offset, 0, sizeof(cam_frame_len_offset_t)); 2786 stream->getFrameOffset(offset); 2787 2788 if (NULL != timeinfo) { 2789 strftime(timeBuf, sizeof(timeBuf), 2790 QCAMERA_DUMP_FRM_LOCATION "%Y%m%d%H%M%S", timeinfo); 2791 } 2792 String8 filePath(timeBuf); 2793 switch (dump_type) { 2794 case QCAMERA_DUMP_FRM_PREVIEW: 2795 { 2796 snprintf(buf, sizeof(buf), "%dp_%dx%d_%d.yuv", 2797 dumpFrmCnt, dim.width, dim.height, frame->frame_idx); 2798 } 2799 break; 2800 case QCAMERA_DUMP_FRM_THUMBNAIL: 2801 { 2802 snprintf(buf, sizeof(buf), "%dt_%dx%d_%d.yuv", 2803 dumpFrmCnt, dim.width, dim.height, frame->frame_idx); 2804 } 2805 break; 2806 case QCAMERA_DUMP_FRM_SNAPSHOT: 2807 { 2808 if (!mParameters.isPostProcScaling()) { 2809 mParameters.getStreamDimension(CAM_STREAM_TYPE_SNAPSHOT, dim); 2810 } else { 2811 stream->getFrameDimension(dim); 2812 } 2813 if (misc != NULL) { 2814 snprintf(buf, sizeof(buf), "%ds_%dx%d_%d_%s.yuv", 2815 dumpFrmCnt, dim.width, dim.height, frame->frame_idx, misc); 2816 } else { 2817 snprintf(buf, sizeof(buf), "%ds_%dx%d_%d.yuv", 2818 dumpFrmCnt, dim.width, dim.height, frame->frame_idx); 2819 } 2820 } 2821 break; 2822 case QCAMERA_DUMP_FRM_INPUT_REPROCESS: 2823 { 2824 stream->getFrameDimension(dim); 2825 if (misc != NULL) { 2826 snprintf(buf, sizeof(buf), "%dir_%dx%d_%d_%s.yuv", 2827 dumpFrmCnt, dim.width, dim.height, frame->frame_idx, misc); 2828 } else { 2829 snprintf(buf, sizeof(buf), "%dir_%dx%d_%d.yuv", 2830 dumpFrmCnt, dim.width, dim.height, frame->frame_idx); 2831 } 2832 } 2833 break; 2834 case QCAMERA_DUMP_FRM_VIDEO: 2835 { 2836 snprintf(buf, sizeof(buf), "%dv_%dx%d_%d.yuv", 2837 dumpFrmCnt, dim.width, dim.height, frame->frame_idx); 2838 } 2839 break; 2840 case QCAMERA_DUMP_FRM_RAW: 2841 { 2842 mParameters.getStreamDimension(CAM_STREAM_TYPE_RAW, dim); 2843 snprintf(buf, sizeof(buf), "%dr_%dx%d_%d.raw", 2844 dumpFrmCnt, dim.width, dim.height, frame->frame_idx); 2845 } 2846 break; 2847 case QCAMERA_DUMP_FRM_JPEG: 2848 { 2849 mParameters.getStreamDimension(CAM_STREAM_TYPE_SNAPSHOT, dim); 2850 snprintf(buf, sizeof(buf), "%dj_%dx%d_%d.yuv", 2851 dumpFrmCnt, dim.width, dim.height, frame->frame_idx); 2852 } 2853 break; 2854 default: 2855 LOGE("Not supported for dumping stream type %d", 2856 dump_type); 2857 return; 2858 } 2859 2860 filePath.append(buf); 2861 int file_fd = open(filePath.string(), O_RDWR | O_CREAT, 0777); 2862 ssize_t written_len = 0; 2863 if (file_fd >= 0) { 2864 void *data = NULL; 2865 2866 fchmod(file_fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 2867 for (uint32_t i = 0; i < offset.num_planes; i++) { 2868 uint32_t index = offset.mp[i].offset; 2869 if (i > 0) { 2870 index += offset.mp[i-1].len; 2871 } 2872 2873 if (offset.mp[i].meta_len != 0) { 2874 data = (void *)((uint8_t *)frame->buffer + index); 2875 written_len += write(file_fd, data, 2876 (size_t)offset.mp[i].meta_len); 2877 index += (uint32_t)offset.mp[i].meta_len; 2878 } 2879 2880 for (int j = 0; j < offset.mp[i].height; j++) { 2881 data = (void *)((uint8_t *)frame->buffer + index); 2882 written_len += write(file_fd, data, 2883 (size_t)offset.mp[i].width); 2884 index += (uint32_t)offset.mp[i].stride; 2885 } 2886 } 2887 2888 LOGH("written number of bytes %zd\n", 2889 written_len); 2890 close(file_fd); 2891 frame->cache_flags |= CPU_HAS_READ; 2892 } else { 2893 LOGE("fail to open file for image dumping"); 2894 } 2895 if (true == m_bIntRawEvtPending) { 2896 strlcpy(m_BackendFileName, filePath.string(), QCAMERA_MAX_FILEPATH_LENGTH); 2897 mBackendFileSize = (size_t)written_len; 2898 } else { 2899 dumpFrmCnt++; 2900 } 2901 } 2902 } 2903 stream->mDumpSkipCnt++; 2904 } 2905 } else { 2906 dumpFrmCnt = 0; 2907 } 2908 stream->mDumpFrame = dumpFrmCnt; 2909 } 2910 2911 /*=========================================================================== 2912 * FUNCTION : debugShowVideoFPS 2913 * 2914 * DESCRIPTION: helper function to log video frame FPS for debug purpose. 2915 * 2916 * PARAMETERS : None 2917 * 2918 * RETURN : None 2919 *==========================================================================*/ 2920 void QCamera2HardwareInterface::debugShowVideoFPS() 2921 { 2922 mVFrameCount++; 2923 nsecs_t now = systemTime(); 2924 nsecs_t diff = now - mVLastFpsTime; 2925 if (diff > ms2ns(250)) { 2926 mVFps = (((double)(mVFrameCount - mVLastFrameCount)) * 2927 (double)(s2ns(1))) / (double)diff; 2928 LOGI("[KPI Perf]: PROFILE_VIDEO_FRAMES_PER_SECOND: %.4f Cam ID = %d", 2929 mVFps, mCameraId); 2930 mVLastFpsTime = now; 2931 mVLastFrameCount = mVFrameCount; 2932 } 2933 } 2934 2935 /*=========================================================================== 2936 * FUNCTION : debugShowPreviewFPS 2937 * 2938 * DESCRIPTION: helper function to log preview frame FPS for debug purpose. 2939 * 2940 * PARAMETERS : None 2941 * 2942 * RETURN : None 2943 *==========================================================================*/ 2944 void QCamera2HardwareInterface::debugShowPreviewFPS() 2945 { 2946 mPFrameCount++; 2947 nsecs_t now = systemTime(); 2948 nsecs_t diff = now - mPLastFpsTime; 2949 if (diff > ms2ns(250)) { 2950 mPFps = (((double)(mPFrameCount - mPLastFrameCount)) * 2951 (double)(s2ns(1))) / (double)diff; 2952 LOGI("[KPI Perf]: PROFILE_PREVIEW_FRAMES_PER_SECOND : %.4f Cam ID = %d", 2953 mPFps, mCameraId); 2954 mPLastFpsTime = now; 2955 mPLastFrameCount = mPFrameCount; 2956 } 2957 } 2958 2959 /*=========================================================================== 2960 * FUNCTION : fillFacesData 2961 * 2962 * DESCRIPTION: helper function to fill in face related metadata into a struct. 2963 * 2964 * PARAMETERS : 2965 * @faces_data : face features data to be filled 2966 * @metadata : metadata structure to read face features from 2967 * 2968 * RETURN : None 2969 *==========================================================================*/ 2970 void QCamera2HardwareInterface::fillFacesData(cam_faces_data_t &faces_data, 2971 metadata_buffer_t *metadata) 2972 { 2973 memset(&faces_data, 0, sizeof(cam_faces_data_t)); 2974 2975 IF_META_AVAILABLE(cam_face_detection_data_t, p_detection_data, 2976 CAM_INTF_META_FACE_DETECTION, metadata) { 2977 faces_data.detection_data = *p_detection_data; 2978 if (faces_data.detection_data.num_faces_detected > MAX_ROI) { 2979 faces_data.detection_data.num_faces_detected = MAX_ROI; 2980 } 2981 2982 LOGH("[KPI Perf] PROFILE_NUMBER_OF_FACES_DETECTED %d", 2983 faces_data.detection_data.num_faces_detected); 2984 2985 IF_META_AVAILABLE(cam_face_recog_data_t, p_recog_data, 2986 CAM_INTF_META_FACE_RECOG, metadata) { 2987 faces_data.recog_valid = true; 2988 faces_data.recog_data = *p_recog_data; 2989 } 2990 2991 IF_META_AVAILABLE(cam_face_blink_data_t, p_blink_data, 2992 CAM_INTF_META_FACE_BLINK, metadata) { 2993 faces_data.blink_valid = true; 2994 faces_data.blink_data = *p_blink_data; 2995 } 2996 2997 IF_META_AVAILABLE(cam_face_gaze_data_t, p_gaze_data, 2998 CAM_INTF_META_FACE_GAZE, metadata) { 2999 faces_data.gaze_valid = true; 3000 faces_data.gaze_data = *p_gaze_data; 3001 } 3002 3003 IF_META_AVAILABLE(cam_face_smile_data_t, p_smile_data, 3004 CAM_INTF_META_FACE_SMILE, metadata) { 3005 faces_data.smile_valid = true; 3006 faces_data.smile_data = *p_smile_data; 3007 } 3008 3009 IF_META_AVAILABLE(cam_face_landmarks_data_t, p_landmarks, 3010 CAM_INTF_META_FACE_LANDMARK, metadata) { 3011 faces_data.landmark_valid = true; 3012 faces_data.landmark_data = *p_landmarks; 3013 } 3014 3015 IF_META_AVAILABLE(cam_face_contour_data_t, p_contour, 3016 CAM_INTF_META_FACE_CONTOUR, metadata) { 3017 faces_data.contour_valid = true; 3018 faces_data.contour_data = *p_contour; 3019 } 3020 } 3021 } 3022 3023 /*=========================================================================== 3024 * FUNCTION : ~QCameraCbNotifier 3025 * 3026 * DESCRIPTION: Destructor for exiting the callback context. 3027 * 3028 * PARAMETERS : None 3029 * 3030 * RETURN : None 3031 *==========================================================================*/ 3032 QCameraCbNotifier::~QCameraCbNotifier() 3033 { 3034 } 3035 3036 /*=========================================================================== 3037 * FUNCTION : exit 3038 * 3039 * DESCRIPTION: exit notify thread. 3040 * 3041 * PARAMETERS : None 3042 * 3043 * RETURN : None 3044 *==========================================================================*/ 3045 void QCameraCbNotifier::exit() 3046 { 3047 mActive = false; 3048 mProcTh.exit(); 3049 } 3050 3051 /*=========================================================================== 3052 * FUNCTION : releaseNotifications 3053 * 3054 * DESCRIPTION: callback for releasing data stored in the callback queue. 3055 * 3056 * PARAMETERS : 3057 * @data : data to be released 3058 * @user_data : context data 3059 * 3060 * RETURN : None 3061 *==========================================================================*/ 3062 void QCameraCbNotifier::releaseNotifications(void *data, void *user_data) 3063 { 3064 qcamera_callback_argm_t *arg = ( qcamera_callback_argm_t * ) data; 3065 3066 if ( ( NULL != arg ) && ( NULL != user_data ) ) { 3067 if ( arg->release_cb ) { 3068 arg->release_cb(arg->user_data, arg->cookie, FAILED_TRANSACTION); 3069 } 3070 } 3071 } 3072 3073 /*=========================================================================== 3074 * FUNCTION : matchSnapshotNotifications 3075 * 3076 * DESCRIPTION: matches snapshot data callbacks 3077 * 3078 * PARAMETERS : 3079 * @data : data to match 3080 * @user_data : context data 3081 * 3082 * RETURN : bool match 3083 * true - match found 3084 * false- match not found 3085 *==========================================================================*/ 3086 bool QCameraCbNotifier::matchSnapshotNotifications(void *data, 3087 void */*user_data*/) 3088 { 3089 qcamera_callback_argm_t *arg = ( qcamera_callback_argm_t * ) data; 3090 if ( NULL != arg ) { 3091 if ( QCAMERA_DATA_SNAPSHOT_CALLBACK == arg->cb_type ) { 3092 return true; 3093 } 3094 } 3095 3096 return false; 3097 } 3098 3099 /*=========================================================================== 3100 * FUNCTION : matchPreviewNotifications 3101 * 3102 * DESCRIPTION: matches preview data callbacks 3103 * 3104 * PARAMETERS : 3105 * @data : data to match 3106 * @user_data : context data 3107 * 3108 * RETURN : bool match 3109 * true - match found 3110 * false- match not found 3111 *==========================================================================*/ 3112 bool QCameraCbNotifier::matchPreviewNotifications(void *data, 3113 void */*user_data*/) 3114 { 3115 qcamera_callback_argm_t *arg = ( qcamera_callback_argm_t * ) data; 3116 if (NULL != arg) { 3117 if ((QCAMERA_DATA_CALLBACK == arg->cb_type) && 3118 (CAMERA_MSG_PREVIEW_FRAME == arg->msg_type)) { 3119 return true; 3120 } 3121 } 3122 3123 return false; 3124 } 3125 3126 /*=========================================================================== 3127 * FUNCTION : matchTimestampNotifications 3128 * 3129 * DESCRIPTION: matches timestamp data callbacks 3130 * 3131 * PARAMETERS : 3132 * @data : data to match 3133 * @user_data : context data 3134 * 3135 * RETURN : bool match 3136 * true - match found 3137 * false- match not found 3138 *==========================================================================*/ 3139 bool QCameraCbNotifier::matchTimestampNotifications(void *data, 3140 void */*user_data*/) 3141 { 3142 qcamera_callback_argm_t *arg = ( qcamera_callback_argm_t * ) data; 3143 if (NULL != arg) { 3144 if ((QCAMERA_DATA_TIMESTAMP_CALLBACK == arg->cb_type) && 3145 (CAMERA_MSG_VIDEO_FRAME == arg->msg_type)) { 3146 return true; 3147 } 3148 } 3149 3150 return false; 3151 } 3152 3153 /*=========================================================================== 3154 * FUNCTION : cbNotifyRoutine 3155 * 3156 * DESCRIPTION: callback thread which interfaces with the upper layers 3157 * given input commands. 3158 * 3159 * PARAMETERS : 3160 * @data : context data 3161 * 3162 * RETURN : None 3163 *==========================================================================*/ 3164 void * QCameraCbNotifier::cbNotifyRoutine(void * data) 3165 { 3166 int running = 1; 3167 int ret; 3168 QCameraCbNotifier *pme = (QCameraCbNotifier *)data; 3169 QCameraCmdThread *cmdThread = &pme->mProcTh; 3170 cmdThread->setName("CAM_cbNotify"); 3171 uint8_t isSnapshotActive = FALSE; 3172 bool longShotEnabled = false; 3173 uint32_t numOfSnapshotExpected = 0; 3174 uint32_t numOfSnapshotRcvd = 0; 3175 int32_t cbStatus = NO_ERROR; 3176 3177 LOGD("E"); 3178 do { 3179 do { 3180 ret = cam_sem_wait(&cmdThread->cmd_sem); 3181 if (ret != 0 && errno != EINVAL) { 3182 LOGD("cam_sem_wait error (%s)", 3183 strerror(errno)); 3184 return NULL; 3185 } 3186 } while (ret != 0); 3187 3188 camera_cmd_type_t cmd = cmdThread->getCmd(); 3189 LOGD("get cmd %d", cmd); 3190 switch (cmd) { 3191 case CAMERA_CMD_TYPE_START_DATA_PROC: 3192 { 3193 isSnapshotActive = TRUE; 3194 numOfSnapshotExpected = pme->mParent->numOfSnapshotsExpected(); 3195 longShotEnabled = pme->mParent->isLongshotEnabled(); 3196 LOGD("Num Snapshots Expected = %d", 3197 numOfSnapshotExpected); 3198 numOfSnapshotRcvd = 0; 3199 } 3200 break; 3201 case CAMERA_CMD_TYPE_STOP_DATA_PROC: 3202 { 3203 pme->mDataQ.flushNodes(matchSnapshotNotifications); 3204 isSnapshotActive = FALSE; 3205 3206 numOfSnapshotExpected = 0; 3207 numOfSnapshotRcvd = 0; 3208 } 3209 break; 3210 case CAMERA_CMD_TYPE_DO_NEXT_JOB: 3211 { 3212 qcamera_callback_argm_t *cb = 3213 (qcamera_callback_argm_t *)pme->mDataQ.dequeue(); 3214 cbStatus = NO_ERROR; 3215 if (NULL != cb) { 3216 LOGD("cb type %d received", 3217 cb->cb_type); 3218 3219 if (pme->mParent->msgTypeEnabledWithLock(cb->msg_type)) { 3220 switch (cb->cb_type) { 3221 case QCAMERA_NOTIFY_CALLBACK: 3222 { 3223 if (cb->msg_type == CAMERA_MSG_FOCUS) { 3224 KPI_ATRACE_INT("Camera:AutoFocus", 0); 3225 LOGH("[KPI Perf] : PROFILE_SENDING_FOCUS_EVT_TO APP"); 3226 } 3227 if (pme->mNotifyCb) { 3228 pme->mNotifyCb(cb->msg_type, 3229 cb->ext1, 3230 cb->ext2, 3231 pme->mCallbackCookie); 3232 } else { 3233 LOGW("notify callback not set!"); 3234 } 3235 if (cb->release_cb) { 3236 cb->release_cb(cb->user_data, cb->cookie, 3237 cbStatus); 3238 } 3239 } 3240 break; 3241 case QCAMERA_DATA_CALLBACK: 3242 { 3243 if (pme->mDataCb) { 3244 pme->mDataCb(cb->msg_type, 3245 cb->data, 3246 cb->index, 3247 cb->metadata, 3248 pme->mCallbackCookie); 3249 } else { 3250 LOGW("data callback not set!"); 3251 } 3252 if (cb->release_cb) { 3253 cb->release_cb(cb->user_data, cb->cookie, 3254 cbStatus); 3255 } 3256 } 3257 break; 3258 case QCAMERA_DATA_TIMESTAMP_CALLBACK: 3259 { 3260 if(pme->mDataCbTimestamp) { 3261 pme->mDataCbTimestamp(cb->timestamp, 3262 cb->msg_type, 3263 cb->data, 3264 cb->index, 3265 pme->mCallbackCookie); 3266 } else { 3267 LOGE("Timestamp data callback not set!"); 3268 } 3269 if (cb->release_cb) { 3270 cb->release_cb(cb->user_data, cb->cookie, 3271 cbStatus); 3272 } 3273 } 3274 break; 3275 case QCAMERA_DATA_SNAPSHOT_CALLBACK: 3276 { 3277 if (TRUE == isSnapshotActive && pme->mDataCb ) { 3278 if (!longShotEnabled) { 3279 numOfSnapshotRcvd++; 3280 LOGI("Num Snapshots Received = %d Expected = %d", 3281 numOfSnapshotRcvd, numOfSnapshotExpected); 3282 if (numOfSnapshotExpected > 0 && 3283 (numOfSnapshotExpected == numOfSnapshotRcvd)) { 3284 LOGI("Received all snapshots"); 3285 // notify HWI that snapshot is done 3286 pme->mParent->processSyncEvt(QCAMERA_SM_EVT_SNAPSHOT_DONE, 3287 NULL); 3288 } 3289 } 3290 if (pme->mJpegCb) { 3291 LOGI("Calling JPEG Callback!! for camera %d" 3292 "release_data %p", 3293 "frame_idx %d", 3294 pme->mParent->getCameraId(), 3295 cb->user_data, 3296 cb->frame_index); 3297 pme->mJpegCb(cb->msg_type, cb->data, 3298 cb->index, cb->metadata, 3299 pme->mJpegCallbackCookie, 3300 cb->frame_index, cb->release_cb, 3301 cb->cookie, cb->user_data); 3302 // incase of non-null Jpeg cb we transfer 3303 // ownership of buffer to muxer. hence 3304 // release_cb should not be called 3305 // muxer will release after its done with 3306 // processing the buffer 3307 } else if(pme->mDataCb){ 3308 pme->mDataCb(cb->msg_type, cb->data, cb->index, 3309 cb->metadata, pme->mCallbackCookie); 3310 if (cb->release_cb) { 3311 cb->release_cb(cb->user_data, cb->cookie, 3312 cbStatus); 3313 } 3314 } 3315 } 3316 } 3317 break; 3318 default: 3319 { 3320 LOGE("invalid cb type %d", 3321 cb->cb_type); 3322 cbStatus = BAD_VALUE; 3323 if (cb->release_cb) { 3324 cb->release_cb(cb->user_data, cb->cookie, 3325 cbStatus); 3326 } 3327 } 3328 break; 3329 }; 3330 } else { 3331 LOGW("cb message type %d not enabled!", 3332 cb->msg_type); 3333 cbStatus = INVALID_OPERATION; 3334 if (cb->release_cb) { 3335 cb->release_cb(cb->user_data, cb->cookie, cbStatus); 3336 } 3337 } 3338 delete cb; 3339 } else { 3340 LOGW("invalid cb type passed"); 3341 } 3342 } 3343 break; 3344 case CAMERA_CMD_TYPE_EXIT: 3345 { 3346 running = 0; 3347 pme->mDataQ.flush(); 3348 } 3349 break; 3350 default: 3351 break; 3352 } 3353 } while (running); 3354 LOGD("X"); 3355 3356 return NULL; 3357 } 3358 3359 /*=========================================================================== 3360 * FUNCTION : notifyCallback 3361 * 3362 * DESCRIPTION: Enqueus pending callback notifications for the upper layers. 3363 * 3364 * PARAMETERS : 3365 * @cbArgs : callback arguments 3366 * 3367 * RETURN : int32_t type of status 3368 * NO_ERROR -- success 3369 * none-zero failure code 3370 *==========================================================================*/ 3371 int32_t QCameraCbNotifier::notifyCallback(qcamera_callback_argm_t &cbArgs) 3372 { 3373 if (!mActive) { 3374 LOGE("notify thread is not active"); 3375 return UNKNOWN_ERROR; 3376 } 3377 3378 qcamera_callback_argm_t *cbArg = new qcamera_callback_argm_t(); 3379 if (NULL == cbArg) { 3380 LOGE("no mem for qcamera_callback_argm_t"); 3381 return NO_MEMORY; 3382 } 3383 memset(cbArg, 0, sizeof(qcamera_callback_argm_t)); 3384 *cbArg = cbArgs; 3385 3386 if (mDataQ.enqueue((void *)cbArg)) { 3387 return mProcTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE); 3388 } else { 3389 LOGE("Error adding cb data into queue"); 3390 delete cbArg; 3391 return UNKNOWN_ERROR; 3392 } 3393 } 3394 3395 /*=========================================================================== 3396 * FUNCTION : setCallbacks 3397 * 3398 * DESCRIPTION: Initializes the callback functions, which would be used for 3399 * communication with the upper layers and launches the callback 3400 * context in which the callbacks will occur. 3401 * 3402 * PARAMETERS : 3403 * @notifyCb : notification callback 3404 * @dataCb : data callback 3405 * @dataCbTimestamp : data with timestamp callback 3406 * @callbackCookie : callback context data 3407 * 3408 * RETURN : None 3409 *==========================================================================*/ 3410 void QCameraCbNotifier::setCallbacks(camera_notify_callback notifyCb, 3411 camera_data_callback dataCb, 3412 camera_data_timestamp_callback dataCbTimestamp, 3413 void *callbackCookie) 3414 { 3415 if ( ( NULL == mNotifyCb ) && 3416 ( NULL == mDataCb ) && 3417 ( NULL == mDataCbTimestamp ) && 3418 ( NULL == mCallbackCookie ) ) { 3419 mNotifyCb = notifyCb; 3420 mDataCb = dataCb; 3421 mDataCbTimestamp = dataCbTimestamp; 3422 mCallbackCookie = callbackCookie; 3423 mActive = true; 3424 mProcTh.launch(cbNotifyRoutine, this); 3425 } else { 3426 LOGE("Camera callback notifier already initialized!"); 3427 } 3428 } 3429 3430 /*=========================================================================== 3431 * FUNCTION : setJpegCallBacks 3432 * 3433 * DESCRIPTION: Initializes the JPEG callback function, which would be used for 3434 * communication with the upper layers and launches the callback 3435 * context in which the callbacks will occur. 3436 * 3437 * PARAMETERS : 3438 * @jpegCb : notification callback 3439 * @callbackCookie : callback context data 3440 * 3441 * RETURN : None 3442 *==========================================================================*/ 3443 void QCameraCbNotifier::setJpegCallBacks( 3444 jpeg_data_callback jpegCb, void *callbackCookie) 3445 { 3446 LOGH("Setting JPEG Callback notifier"); 3447 mJpegCb = jpegCb; 3448 mJpegCallbackCookie = callbackCookie; 3449 } 3450 3451 /*=========================================================================== 3452 * FUNCTION : flushPreviewNotifications 3453 * 3454 * DESCRIPTION: flush all pending preview notifications 3455 * from the notifier queue 3456 * 3457 * PARAMETERS : None 3458 * 3459 * RETURN : int32_t type of status 3460 * NO_ERROR -- success 3461 * none-zero failure code 3462 *==========================================================================*/ 3463 int32_t QCameraCbNotifier::flushPreviewNotifications() 3464 { 3465 if (!mActive) { 3466 LOGE("notify thread is not active"); 3467 return UNKNOWN_ERROR; 3468 } 3469 mDataQ.flushNodes(matchPreviewNotifications); 3470 return NO_ERROR; 3471 } 3472 3473 /*=========================================================================== 3474 * FUNCTION : flushVideoNotifications 3475 * 3476 * DESCRIPTION: flush all pending video notifications 3477 * from the notifier queue 3478 * 3479 * PARAMETERS : None 3480 * 3481 * RETURN : int32_t type of status 3482 * NO_ERROR -- success 3483 * none-zero failure code 3484 *==========================================================================*/ 3485 int32_t QCameraCbNotifier::flushVideoNotifications() 3486 { 3487 if (!mActive) { 3488 LOGE("notify thread is not active"); 3489 return UNKNOWN_ERROR; 3490 } 3491 mDataQ.flushNodes(matchTimestampNotifications); 3492 return NO_ERROR; 3493 } 3494 3495 /*=========================================================================== 3496 * FUNCTION : startSnapshots 3497 * 3498 * DESCRIPTION: Enables snapshot mode 3499 * 3500 * PARAMETERS : None 3501 * 3502 * RETURN : int32_t type of status 3503 * NO_ERROR -- success 3504 * none-zero failure code 3505 *==========================================================================*/ 3506 int32_t QCameraCbNotifier::startSnapshots() 3507 { 3508 return mProcTh.sendCmd(CAMERA_CMD_TYPE_START_DATA_PROC, FALSE, TRUE); 3509 } 3510 3511 /*=========================================================================== 3512 * FUNCTION : stopSnapshots 3513 * 3514 * DESCRIPTION: Disables snapshot processing mode 3515 * 3516 * PARAMETERS : None 3517 * 3518 * RETURN : None 3519 *==========================================================================*/ 3520 void QCameraCbNotifier::stopSnapshots() 3521 { 3522 mProcTh.sendCmd(CAMERA_CMD_TYPE_STOP_DATA_PROC, FALSE, TRUE); 3523 } 3524 3525 }; // namespace qcamera 3526