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