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