Home | History | Annotate | Download | only in util
      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