1 /* Copyright (c) 2016-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 "DualFOVPP" 31 // System dependencies 32 #include <dlfcn.h> 33 #include <utils/Errors.h> 34 #include <stdio.h> 35 #include <stdlib.h> 36 // Camera dependencies 37 #include "QCameraDualFOVPP.h" 38 #include "QCameraTrace.h" 39 #include "cam_intf.h" 40 extern "C" { 41 #include "mm_camera_dbg.h" 42 } 43 44 #define LIB_PATH_LENGTH 100 45 46 namespace qcamera { 47 48 /*=========================================================================== 49 * FUNCTION : QCameraDualFOVPP 50 * 51 * DESCRIPTION: constructor of QCameraDualFOVPP. 52 * 53 * PARAMETERS : None 54 * 55 * RETURN : None 56 *==========================================================================*/ 57 QCameraDualFOVPP::QCameraDualFOVPP() 58 : QCameraHALPP() 59 { 60 m_dlHandle = NULL; 61 m_pCaps = NULL; 62 } 63 64 /*=========================================================================== 65 * FUNCTION : ~QCameraDualFOVPP 66 * 67 * DESCRIPTION: destructor of QCameraDualFOVPP. 68 * 69 * PARAMETERS : None 70 * 71 * RETURN : None 72 *==========================================================================*/ 73 QCameraDualFOVPP::~QCameraDualFOVPP() 74 { 75 } 76 77 /*=========================================================================== 78 * FUNCTION : init 79 * 80 * DESCRIPTION: initialization of QCameraDualFOVPP 81 * 82 * PARAMETERS : 83 * @bufNotifyCb : call back function after HALPP process 84 * @getOutputCb : call back function to request output buffe 85 * @pUserData : Parent of HALPP, i.e. QCameraPostProc 86 * @pStaticParam : holds dual camera calibration data in an array and its size 87 * (expected size is 264 bytes) 88 * 89 * RETURN : int32_t type of status 90 * NO_ERROR -- success 91 * none-zero failure code 92 *==========================================================================*/ 93 int32_t QCameraDualFOVPP::init(halPPBufNotify bufNotifyCb, halPPGetOutput getOutputCb, 94 void *pUserData, void *pStaticParam) 95 { 96 LOGD("E"); 97 int32_t rc = NO_ERROR; 98 QCameraHALPP::init(bufNotifyCb, getOutputCb, pUserData); 99 100 m_pCaps = (cam_capability_t *)pStaticParam; 101 102 /* we should load 3rd libs here, with dlopen/dlsym */ 103 doDualFovPPInit(); 104 105 LOGD("X"); 106 return rc; 107 } 108 109 /*=========================================================================== 110 * FUNCTION : deinit 111 * 112 * DESCRIPTION: de initialization of QCameraDualFOVPP 113 * 114 * PARAMETERS : None 115 * 116 * RETURN : int32_t type of status 117 * NO_ERROR -- success 118 * none-zero failure code 119 *==========================================================================*/ 120 int32_t QCameraDualFOVPP::deinit() 121 { 122 int32_t rc = NO_ERROR; 123 LOGD("E"); 124 125 m_dlHandle = NULL; 126 127 QCameraHALPP::deinit(); 128 LOGD("X"); 129 return rc; 130 } 131 132 /*=========================================================================== 133 * FUNCTION : start 134 * 135 * DESCRIPTION: starting QCameraDualFOVPP 136 * 137 * PARAMETERS : 138 * 139 * RETURN : int32_t type of status 140 * NO_ERROR -- success 141 * none-zero failure code 142 *==========================================================================*/ 143 int32_t QCameraDualFOVPP::start() 144 { 145 int32_t rc = NO_ERROR; 146 LOGD("E"); 147 148 rc = QCameraHALPP::start(); 149 150 LOGD("X"); 151 return rc; 152 } 153 154 155 /*=========================================================================== 156 * FUNCTION : feedInput 157 * 158 * DESCRIPTION: function to feed input data. 159 * Enqueue the frame index to inputQ if it is new frame 160 * Also, add the input image data to frame hash map 161 * 162 * PARAMETERS : 163 * @pInput : ptr to input data 164 * 165 * RETURN : int32_t type of status 166 * NO_ERROR -- success 167 * none-zero failure code 168 *==========================================================================*/ 169 int32_t QCameraDualFOVPP::feedInput(qcamera_hal_pp_data_t *pInputData) 170 { 171 int32_t rc = NO_ERROR; 172 LOGD("E"); 173 if (NULL != pInputData) { 174 QCameraStream* pSnapshotStream = NULL; 175 mm_camera_buf_def_t *pInputSnapshotBuf = getSnapshotBuf(pInputData, pSnapshotStream); 176 if (pInputSnapshotBuf != NULL) { 177 uint32_t frameIndex = pInputSnapshotBuf->frame_idx; 178 std::vector<qcamera_hal_pp_data_t*> *pVector = getFrameVector(frameIndex); 179 if(pVector == NULL) { 180 LOGD("insert new frame index = %d", frameIndex); 181 uint32_t *pFrameIndex = new uint32_t; 182 *pFrameIndex = frameIndex; 183 // new the vector first 184 pVector = new std::vector<qcamera_hal_pp_data_t*>(WIDE_TELE_CAMERA_NUMBER); 185 pVector->at(WIDE_INPUT) = NULL; 186 pVector->at(TELE_INPUT) = NULL; 187 // Add vector to the hash map 188 m_frameMap[frameIndex] = pVector; 189 // Enqueue the frame index (i.e. key of vector) to queue 190 if (false == m_iuputQ.enqueue((void*)pFrameIndex)) { 191 LOGE("Input Q is not active!!!"); 192 releaseData(pInputData); 193 m_frameMap.erase(frameIndex); 194 delete pFrameIndex; 195 delete pVector; 196 rc = INVALID_OPERATION; 197 return rc; 198 } 199 } 200 pInputData->frameIndex = frameIndex; 201 // Check if frame is from main wide camera 202 bool bIsMain = true; 203 uint32_t mainHandle = get_main_camera_handle( 204 pInputData->src_reproc_frame->camera_handle); 205 if (mainHandle == 0) { 206 bIsMain = false; 207 } 208 LOGD("mainHandle = %d, is main frame = %d", mainHandle, bIsMain); 209 // Add input data to vector 210 if (bIsMain) { 211 pVector->at(WIDE_INPUT) = pInputData; 212 } else { 213 pVector->at(TELE_INPUT) = pInputData; 214 } 215 216 // request output buffer only if both wide and tele input data are recieved 217 if (pVector->at(0) != NULL && pVector->at(1) != NULL) { 218 m_halPPGetOutputCB(frameIndex, m_pQCameraPostProc); 219 } 220 } 221 } else { 222 LOGE("pInput is NULL"); 223 rc = UNEXPECTED_NULL; 224 } 225 LOGD("X"); 226 return rc; 227 } 228 229 /*=========================================================================== 230 * FUNCTION : feedOutput 231 * 232 * DESCRIPTION: function to feed output buffer and metadata 233 * 234 * PARAMETERS : 235 * @pOutput : ptr to output data 236 * 237 * RETURN : int32_t type of status 238 * NO_ERROR -- success 239 * none-zero failure code 240 *==========================================================================*/ 241 int32_t QCameraDualFOVPP::feedOutput(qcamera_hal_pp_data_t *pOutputData) 242 { 243 int32_t rc = NO_ERROR; 244 LOGD("E"); 245 if (NULL != pOutputData) { 246 uint32_t frameIndex = pOutputData->frameIndex; 247 std::vector<qcamera_hal_pp_data_t*> *pVector = getFrameVector(frameIndex); 248 // Get the main (Wide) input frame in order to get output buffer len, 249 // and copy metadata buffer. 250 if (pVector != NULL && pVector->at(WIDE_INPUT) != NULL) { 251 qcamera_hal_pp_data_t *pInputData = pVector->at(WIDE_INPUT); 252 mm_camera_super_buf_t *pInputFrame = pInputData->frame; 253 QCameraStream* pSnapshotStream = NULL; 254 QCameraStream* pMetadataStream = NULL; 255 mm_camera_buf_def_t *pInputSnapshotBuf = getSnapshotBuf(pInputData, pSnapshotStream); 256 mm_camera_buf_def_t *pInputMetadataBuf = getMetadataBuf(pInputData, pMetadataStream); 257 mm_camera_super_buf_t *pOutputFrame = pOutputData->frame; 258 mm_camera_buf_def_t *pOutputBufDefs = pOutputData->bufs; 259 260 if (pInputSnapshotBuf == NULL || pInputMetadataBuf == NULL) { 261 LOGE("cannot get sanpshot or metadata buf def"); 262 releaseData(pOutputData); 263 return UNEXPECTED_NULL; 264 } 265 if (pSnapshotStream == NULL || pMetadataStream == NULL) { 266 LOGE("cannot get sanpshot or metadata stream"); 267 releaseData(pOutputData); 268 return UNEXPECTED_NULL; 269 } 270 271 // Copy main input frame info to output frame 272 pOutputFrame->camera_handle = pInputFrame->camera_handle; 273 pOutputFrame->ch_id = pInputFrame->ch_id; 274 pOutputFrame->num_bufs = HAL_PP_NUM_BUFS;//snapshot and metadata 275 pOutputFrame->bUnlockAEC = pInputFrame->bUnlockAEC; 276 pOutputFrame->bReadyForPrepareSnapshot = pInputFrame->bReadyForPrepareSnapshot; 277 278 // Reconstruction of output_frame super buffer 279 pOutputFrame->bufs[0] = &pOutputBufDefs[0]; 280 pOutputFrame->bufs[1] = &pOutputBufDefs[1]; 281 282 // Allocate heap buffer for output image frame 283 cam_frame_len_offset_t offset; 284 memset(&offset, 0, sizeof(cam_frame_len_offset_t)); 285 LOGD("pInputSnapshotBuf->frame_len = %d", pInputSnapshotBuf->frame_len); 286 rc = pOutputData->snapshot_heap->allocate(1, pInputSnapshotBuf->frame_len); 287 if (rc < 0) { 288 LOGE("Unable to allocate heap memory for image buf"); 289 releaseData(pOutputData); 290 return NO_MEMORY; 291 } 292 pSnapshotStream->getFrameOffset(offset); 293 memcpy(&pOutputBufDefs[0], pInputSnapshotBuf, sizeof(mm_camera_buf_def_t)); 294 LOGD("pOutputFrame->bufs[0]->fd = %d, pOutputFrame->bufs[0]->buffer = %x", 295 pOutputFrame->bufs[0]->fd, pOutputFrame->bufs[0]->buffer); 296 pOutputData->snapshot_heap->getBufDef(offset, pOutputBufDefs[0], 0); 297 LOGD("pOutputFrame->bufs[0]->fd = %d, pOutputFrame->bufs[0]->buffer = %x", 298 pOutputFrame->bufs[0]->fd, pOutputFrame->bufs[0]->buffer); 299 300 // Allocate heap buffer for output metadata 301 LOGD("pInputMetadataBuf->frame_len = %d", pInputMetadataBuf->frame_len); 302 rc = pOutputData->metadata_heap->allocate(1, pInputMetadataBuf->frame_len); 303 if (rc < 0) { 304 LOGE("Unable to allocate heap memory for metadata buf"); 305 releaseData(pOutputData); 306 return NO_MEMORY; 307 } 308 memset(&offset, 0, sizeof(cam_frame_len_offset_t)); 309 pMetadataStream->getFrameOffset(offset); 310 memcpy(&pOutputBufDefs[1], pInputMetadataBuf, sizeof(mm_camera_buf_def_t)); 311 pOutputData->metadata_heap->getBufDef(offset, pOutputBufDefs[1], 0); 312 // copy the whole metadata 313 memcpy(pOutputBufDefs[1].buffer, pInputMetadataBuf->buffer, 314 pInputMetadataBuf->frame_len); 315 316 // Enqueue output_data to m_outgoingQ 317 if (false == m_outgoingQ.enqueue((void *)pOutputData)) { 318 LOGE("outgoing Q is not active!!!"); 319 releaseData(pOutputData); 320 rc = INVALID_OPERATION; 321 } 322 } 323 } else { 324 LOGE("pOutput is NULL"); 325 rc = UNEXPECTED_NULL; 326 } 327 LOGD("X"); 328 return rc; 329 } 330 331 /*=========================================================================== 332 * FUNCTION : process 333 * 334 * DESCRIPTION: function to start CP FOV blending process 335 * 336 * PARAMETERS : None 337 * 338 * RETURN : int32_t type of status 339 * NO_ERROR -- success 340 * none-zero failure code 341 *==========================================================================*/ 342 int32_t QCameraDualFOVPP::process() 343 { 344 int32_t rc = NO_ERROR; 345 346 /* dump in/out frames */ 347 char prop[PROPERTY_VALUE_MAX]; 348 memset(prop, 0, sizeof(prop)); 349 property_get("persist.camera.dualfov.dumpimg", prop, "0"); 350 int dumpimg = atoi(prop); 351 352 LOGD("E"); 353 354 // TODO: dequeue from m_inputQ and start process logic 355 // Start the blending process when it is ready 356 if (canProcess()) { 357 LOGI("start Dual FOV process"); 358 uint32_t *pFrameIndex = (uint32_t *)m_iuputQ.dequeue(); 359 if (pFrameIndex == NULL) { 360 LOGE("frame index is null"); 361 return UNEXPECTED_NULL; 362 } 363 uint32_t frameIndex = *pFrameIndex; 364 std::vector<qcamera_hal_pp_data_t*> *pVector = getFrameVector(frameIndex); 365 // Search vector of input frames in frame map 366 if (pVector == NULL) { 367 LOGE("Cannot find vecotr of input frames"); 368 return UNEXPECTED_NULL; 369 } 370 // Get input and output frame buffer 371 qcamera_hal_pp_data_t *pInputMainData = 372 (qcamera_hal_pp_data_t *)pVector->at(WIDE_INPUT); 373 if (pInputMainData == NULL) { 374 LOGE("Cannot find input main data"); 375 return UNEXPECTED_NULL; 376 } 377 if (pInputMainData->src_reproc_frame == NULL) { 378 LOGI("process pInputMainData->src_reproc_frame = NULL"); 379 } 380 //mm_camera_super_buf_t *input_main_frame = input_main_data->frame; 381 qcamera_hal_pp_data_t *pInputAuxData = 382 (qcamera_hal_pp_data_t *)pVector->at(TELE_INPUT); 383 if (pInputAuxData == NULL) { 384 LOGE("Cannot find input aux data"); 385 return UNEXPECTED_NULL; 386 } 387 388 //mm_camera_super_buf_t *input_aux_frame = input_aux_data->frame; 389 qcamera_hal_pp_data_t *pOutputData = 390 (qcamera_hal_pp_data_t*)m_outgoingQ.dequeue(); 391 if (pOutputData == NULL) { 392 LOGE("Cannot find output data"); 393 return UNEXPECTED_NULL; 394 } 395 396 QCameraStream* pMainSnapshotStream = NULL; 397 QCameraStream* pMainMetadataStream = NULL; 398 QCameraStream* pAuxSnapshotStream = NULL; 399 QCameraStream* pAuxMetadataStream = NULL; 400 401 mm_camera_buf_def_t *main_snapshot_buf = 402 getSnapshotBuf(pInputMainData, pMainSnapshotStream); 403 if (main_snapshot_buf == NULL) { 404 LOGE("main_snapshot_buf is NULL"); 405 return UNEXPECTED_NULL; 406 } 407 mm_camera_buf_def_t *main_meta_buf = getMetadataBuf(pInputMainData, pMainMetadataStream); 408 if (main_meta_buf == NULL) { 409 LOGE("main_meta_buf is NULL"); 410 return UNEXPECTED_NULL; 411 } 412 mm_camera_buf_def_t *aux_snapshot_buf = getSnapshotBuf(pInputAuxData, pAuxSnapshotStream); 413 if (aux_snapshot_buf == NULL) { 414 LOGE("aux_snapshot_buf is NULL"); 415 return UNEXPECTED_NULL; 416 } 417 mm_camera_buf_def_t *aux_meta_buf = getMetadataBuf(pInputAuxData, pAuxMetadataStream); 418 if (aux_meta_buf == NULL) { 419 LOGE("aux_meta_buf is NULL"); 420 return UNEXPECTED_NULL; 421 } 422 423 mm_camera_super_buf_t *output_frame = pOutputData->frame; 424 mm_camera_buf_def_t *output_snapshot_buf = output_frame->bufs[0]; 425 426 // Use offset info from reproc stream 427 if (pMainSnapshotStream == NULL) { 428 LOGE("pMainSnapshotStream is NULL"); 429 return UNEXPECTED_NULL; 430 } 431 cam_frame_len_offset_t frm_offset; 432 pMainSnapshotStream->getFrameOffset(frm_offset); 433 LOGI("Stream type:%d, stride:%d, scanline:%d, frame len:%d", 434 pMainSnapshotStream->getMyType(), 435 frm_offset.mp[0].stride, frm_offset.mp[0].scanline, 436 frm_offset.frame_len); 437 438 if (dumpimg) { 439 dumpYUVtoFile((uint8_t *)main_snapshot_buf->buffer, frm_offset, 440 main_snapshot_buf->frame_idx, "wide"); 441 dumpYUVtoFile((uint8_t *)aux_snapshot_buf->buffer, frm_offset, 442 aux_snapshot_buf->frame_idx, "tele"); 443 } 444 445 //Get input and output parameter 446 dualfov_input_params_t inParams; 447 if (pAuxSnapshotStream == NULL) { 448 LOGE("pAuxSnapshotStream is NULL"); 449 return UNEXPECTED_NULL; 450 } 451 getInputParams(main_meta_buf, aux_meta_buf, pMainSnapshotStream, pAuxSnapshotStream, 452 inParams); 453 dumpInputParams(inParams); 454 455 doDualFovPPProcess((const uint8_t *)main_snapshot_buf->buffer, 456 (const uint8_t *)aux_snapshot_buf->buffer, 457 inParams, 458 (uint8_t *)output_snapshot_buf->buffer); 459 460 if (dumpimg) { 461 dumpYUVtoFile((uint8_t *)output_snapshot_buf->buffer, frm_offset, 462 main_snapshot_buf->frame_idx, "out"); 463 } 464 465 /* clean and invalidate caches, for input and output buffers*/ 466 pOutputData->snapshot_heap->cleanInvalidateCache(0); 467 468 QCameraMemory *pMem = (QCameraMemory *)main_snapshot_buf->mem_info; 469 pMem->invalidateCache(main_snapshot_buf->buf_idx); 470 471 pMem = (QCameraMemory *)aux_snapshot_buf->mem_info; 472 pMem->invalidateCache(aux_snapshot_buf->buf_idx); 473 474 475 // Calling cb function to return output_data after processed. 476 m_halPPBufNotifyCB(pOutputData, m_pQCameraPostProc); 477 478 // also send input buffer to postproc. 479 m_halPPBufNotifyCB(pInputMainData, m_pQCameraPostProc); 480 m_halPPBufNotifyCB(pInputAuxData, m_pQCameraPostProc); 481 //releaseData(pInputMainData); 482 //releaseData(pInputAuxData); 483 484 // Release internal resource 485 m_frameMap.erase(frameIndex); 486 delete pFrameIndex; 487 delete pVector; 488 } 489 LOGD("X"); 490 return rc; 491 } 492 493 /*=========================================================================== 494 * FUNCTION : getSnapshotBuf 495 * 496 * DESCRIPTION: function to get snapshot buf def and the stream from frame 497 * PARAMETERS : 498 * @pData : input frame super buffer 499 * @pSnapshotStream : stream of snapshot that found 500 * RETURN : snapshot buf def 501 *==========================================================================*/ 502 mm_camera_buf_def_t* QCameraDualFOVPP::getSnapshotBuf(qcamera_hal_pp_data_t* pData, 503 QCameraStream* &pSnapshotStream) 504 { 505 mm_camera_buf_def_t *pBufDef = NULL; 506 if (pData == NULL) { 507 LOGE("Cannot find input frame super buffer"); 508 return pBufDef; 509 } 510 mm_camera_super_buf_t *pFrame = pData->frame; 511 QCameraChannel *pChannel = m_pQCameraPostProc->getChannelByHandle(pFrame->ch_id); 512 if (pChannel == NULL) { 513 LOGE("Cannot find channel"); 514 return pBufDef; 515 } 516 // Search for input snapshot frame buf 517 for (uint32_t i = 0; i < pFrame->num_bufs; i++) { 518 pSnapshotStream = pChannel->getStreamByHandle(pFrame->bufs[i]->stream_id); 519 if (pSnapshotStream != NULL) { 520 if (pSnapshotStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT) || 521 pSnapshotStream->isOrignalTypeOf(CAM_STREAM_TYPE_SNAPSHOT)) { 522 pBufDef = pFrame->bufs[i]; 523 break; 524 } 525 } 526 } 527 return pBufDef; 528 } 529 530 /*=========================================================================== 531 * FUNCTION : getMetadataBuf 532 * 533 * DESCRIPTION: function to get metadata buf def and the stream from frame 534 * PARAMETERS : 535 * @pData : input frame super buffer 536 * @pMetadataStream : stream of metadata that found 537 * RETURN : metadata buf def 538 *==========================================================================*/ 539 mm_camera_buf_def_t* QCameraDualFOVPP::getMetadataBuf(qcamera_hal_pp_data_t *pData, 540 QCameraStream* &pMetadataStream) 541 { 542 mm_camera_buf_def_t *pBufDef = NULL; 543 if (pData == NULL) { 544 LOGE("Cannot find input frame super buffer"); 545 return pBufDef; 546 } 547 mm_camera_super_buf_t* pFrame = pData->frame; 548 QCameraChannel *pChannel = 549 m_pQCameraPostProc->getChannelByHandle(pData->src_reproc_frame->ch_id); 550 LOGD("src_reproc_frame num_bufs = %d", pFrame->num_bufs); 551 if (pChannel == NULL) { 552 LOGE("Cannot find src_reproc_frame channel"); 553 return pBufDef; 554 } 555 for (uint32_t i = 0; 556 (i < pData->src_reproc_frame->num_bufs); i++) { 557 pMetadataStream = pChannel->getStreamByHandle(pData->src_reproc_frame->bufs[i]->stream_id); 558 if (pData->src_reproc_frame->bufs[i]->stream_type == CAM_STREAM_TYPE_METADATA) { 559 pBufDef = pData->src_reproc_frame->bufs[i]; 560 LOGD("find metadata stream and buf from src_reproc_frame"); 561 break; 562 } 563 } 564 if (pBufDef == NULL) { 565 LOGD("frame num_bufs = %d", pFrame->num_bufs); 566 pChannel = m_pQCameraPostProc->getChannelByHandle(pFrame->ch_id); 567 if (pChannel == NULL) { 568 LOGE("Cannot find frame channel"); 569 return pBufDef; 570 } 571 for (uint32_t i = 0; i < pFrame->num_bufs; i++) { 572 pMetadataStream = pChannel->getStreamByHandle(pFrame->bufs[i]->stream_id); 573 if (pMetadataStream != NULL) { 574 LOGD("bufs[%d] stream_type = %d", i, pFrame->bufs[i]->stream_type); 575 if (pFrame->bufs[i]->stream_type == CAM_STREAM_TYPE_METADATA) { 576 pBufDef = pFrame->bufs[i]; 577 break; 578 } 579 } 580 } 581 } 582 return pBufDef; 583 } 584 585 /*=========================================================================== 586 * FUNCTION : canProcess 587 * 588 * DESCRIPTION: function to release internal resources 589 * RETURN : If CP FOV can start blending process 590 *==========================================================================*/ 591 bool QCameraDualFOVPP::canProcess() 592 { 593 LOGD("E"); 594 bool ready = false; 595 if(!m_iuputQ.isEmpty() && !m_outgoingQ.isEmpty()) { 596 ready = true; 597 } 598 LOGD("X"); 599 return ready; 600 } 601 602 /*=========================================================================== 603 * FUNCTION : getInputParams 604 * 605 * DESCRIPTION: Helper function to get input params from input metadata 606 *==========================================================================*/ 607 void QCameraDualFOVPP::getInputParams(mm_camera_buf_def_t *pMainMetaBuf, 608 mm_camera_buf_def_t *pAuxMetaBuf, QCameraStream* pMainSnapshotStream, 609 QCameraStream* pAuxSnapshotStream, dualfov_input_params_t& inParams) 610 { 611 LOGD("E"); 612 memset(&inParams, 0, sizeof(dualfov_input_params_t)); 613 metadata_buffer_t *pMainMeta = (metadata_buffer_t *)pMainMetaBuf->buffer; 614 metadata_buffer_t *pAuxMeta = (metadata_buffer_t *)pAuxMetaBuf->buffer; 615 616 // Wide frame size 617 cam_frame_len_offset_t offset; 618 pMainSnapshotStream->getFrameOffset(offset); 619 inParams.wide.width = offset.mp[0].width; 620 inParams.wide.height = offset.mp[0].height; 621 inParams.wide.stride = offset.mp[0].stride; 622 inParams.wide.scanline = offset.mp[0].scanline; 623 inParams.wide.frame_len = offset.frame_len; 624 625 // Tele frame size 626 pAuxSnapshotStream->getFrameOffset(offset); 627 inParams.tele.width = offset.mp[0].width; 628 inParams.tele.height = offset.mp[0].height; 629 inParams.tele.stride = offset.mp[0].stride; 630 inParams.tele.scanline = offset.mp[0].scanline; 631 inParams.tele.frame_len = offset.frame_len; 632 633 // user_zoom 634 int32_t zoom_level = -1; // 0 means zoom 1x. 635 IF_META_AVAILABLE(int32_t, userZoom, CAM_INTF_PARM_ZOOM, pMainMeta) { 636 zoom_level = *userZoom; 637 LOGD("zoom level in main meta:%d", zoom_level); 638 } 639 inParams.user_zoom= getUserZoomRatio(zoom_level); 640 LOGI("dual fov total zoom ratio: %d", inParams.user_zoom); 641 642 IF_META_AVAILABLE(int32_t, auxUserZoom, CAM_INTF_PARM_ZOOM, pAuxMeta) { 643 LOGD("zoom level in aux meta:%d", *auxUserZoom); 644 } 645 646 IF_META_AVAILABLE(uint32_t, afState, CAM_INTF_META_AF_STATE, pMainMeta) { 647 if (((*afState) == CAM_AF_STATE_FOCUSED_LOCKED) || 648 ((*afState) == CAM_AF_STATE_PASSIVE_FOCUSED)) { 649 inParams.af_status = AF_STATUS_VALID; 650 } else { 651 inParams.af_status = AF_STATUS_INVALID; 652 } 653 LOGD("af state:%d, output af status:%d", *afState, inParams.af_status); 654 } 655 656 IF_META_AVAILABLE(uint32_t, auxAfState, CAM_INTF_META_AF_STATE, pAuxMeta) { 657 int aux_af_status = 0; 658 if (((*auxAfState) == CAM_AF_STATE_FOCUSED_LOCKED) || 659 ((*auxAfState) == CAM_AF_STATE_PASSIVE_FOCUSED)) { 660 aux_af_status = AF_STATUS_VALID; 661 } else { 662 aux_af_status = AF_STATUS_INVALID; 663 } 664 LOGD("aux af state:%d, output af status:%d", *auxAfState, aux_af_status); 665 } 666 667 668 LOGD("X"); 669 } 670 671 672 int32_t QCameraDualFOVPP::doDualFovPPInit() 673 { 674 LOGD("E"); 675 int rc = NO_ERROR; 676 677 LOGD("X"); 678 return rc; 679 } 680 681 int32_t QCameraDualFOVPP::doDualFovPPProcess(const uint8_t* pWide, const uint8_t* pTele, 682 dualfov_input_params_t inParams, 683 uint8_t* pOut) 684 { 685 LOGW("E."); 686 687 // trace begin 688 689 // half image from main, and half image from tele 690 691 // Y 692 memcpy(pOut, pWide, inParams.wide.stride * inParams.wide.scanline / 2); 693 memcpy(pOut + inParams.wide.stride * inParams.wide.scanline / 2, 694 pTele + inParams.wide.stride * inParams.wide.scanline / 2, 695 inParams.wide.stride * inParams.wide.scanline / 2); 696 697 // UV 698 uint32_t uv_offset = inParams.wide.stride * inParams.wide.scanline; 699 memcpy(pOut + uv_offset, 700 pWide + uv_offset, 701 inParams.wide.stride * (inParams.wide.scanline / 2) / 2); 702 memcpy(pOut + uv_offset + inParams.wide.stride * (inParams.wide.scanline / 2) / 2, 703 pTele + uv_offset + inParams.wide.stride * (inParams.wide.scanline / 2) / 2, 704 inParams.wide.stride * (inParams.wide.scanline / 2) / 2); 705 706 // trace end 707 708 LOGW("X."); 709 return NO_ERROR; 710 } 711 712 uint32_t QCameraDualFOVPP::getUserZoomRatio(int32_t zoom_level) 713 { 714 uint32_t zoom_ratio = 4096; 715 716 LOGD("E. input zoom level:%d", zoom_level); 717 718 if (zoom_level < 0) { 719 LOGW("invalid zoom evel!"); 720 /* got the zoom value from QCamera2HWI Parameters */ 721 zoom_level = 0; 722 } 723 724 // user_zoom_ratio = qcom_zoom_ratio * 4096 / 100 725 if (m_pCaps != NULL) { 726 zoom_ratio *= m_pCaps->zoom_ratio_tbl[zoom_level]; 727 zoom_ratio /= 100; 728 LOGD("converted zoom ratio:%d", zoom_ratio); 729 } 730 731 LOGD("X. zoom_ratio:%d", zoom_ratio); 732 return zoom_ratio; 733 } 734 735 void QCameraDualFOVPP::dumpYUVtoFile(const uint8_t* pBuf, cam_frame_len_offset_t offset, uint32_t idx, const char* name_prefix) 736 { 737 LOGD("E."); 738 char filename[256]; 739 740 snprintf(filename, sizeof(filename), QCAMERA_DUMP_FRM_LOCATION"%s_%dx%d_%d.yuv", 741 name_prefix, offset.mp[0].stride, offset.mp[0].scanline, idx); 742 743 QCameraHALPP::dumpYUVtoFile(pBuf,(const char*)filename, offset.frame_len); 744 745 LOGD("X."); 746 } 747 748 void QCameraDualFOVPP::dumpInputParams(const dualfov_input_params_t& p) 749 { 750 LOGD("E"); 751 752 const cam_frame_size_t* s = NULL; 753 754 s = &p.wide; 755 LOGD("wide frame size: %d, %d, stride:%d, scanline:%d", 756 s->width, s->height, s->stride, s->scanline); 757 758 s = &p.tele; 759 LOGD("wide frame size: %d, %d, stride:%d, scanline:%d", 760 s->width, s->height, s->stride, s->scanline); 761 762 LOGD("zoom ratio: %f", p.user_zoom / 4096.0); 763 LOGD("X"); 764 } 765 766 767 /*=========================================================================== 768 * FUNCTION : dumpOISData 769 * 770 * DESCRIPTION: Read Sensor OIS data from metadata and dump it 771 * 772 * PARAMETERS : 773 * @pMetadata : Frame metadata 774 * 775 * RETURN : None 776 * 777 *==========================================================================*/ 778 void QCameraDualFOVPP::dumpOISData(metadata_buffer_t* pMetadata) 779 { 780 if (!pMetadata) { 781 LOGD("OIS data not available"); 782 return; 783 } 784 785 IF_META_AVAILABLE(cam_ois_data_t, pOisData, CAM_INTF_META_OIS_READ_DATA, pMetadata) { 786 LOGD("Ois Data: data size: %d", pOisData->size); 787 uint8_t *data = pOisData->data; 788 if (pOisData->size == 8) { 789 LOGD("Ois Data Buffer : %d %d %d %d %d %d %d %d ", 790 data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); 791 } 792 } 793 return; 794 } 795 796 797 } // namespace qcamera 798