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