Home | History | Annotate | Download | only in HAL
      1 /* Copyright (c) 2012-2015, The Linux Foundataion. 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 #define ATRACE_TAG ATRACE_TAG_CAMERA
     32 
     33 #include <time.h>
     34 #include <fcntl.h>
     35 #include <sys/stat.h>
     36 #include <utils/Errors.h>
     37 #include <utils/Trace.h>
     38 #include <utils/Timers.h>
     39 #include <QComOMXMetadata.h>
     40 #include "QCamera2HWI.h"
     41 
     42 namespace qcamera {
     43 
     44 /*===========================================================================
     45  * FUNCTION   : zsl_channel_cb
     46  *
     47  * DESCRIPTION: helper function to handle ZSL superbuf callback directly from
     48  *              mm-camera-interface
     49  *
     50  * PARAMETERS :
     51  *   @recvd_frame : received super buffer
     52  *   @userdata    : user data ptr
     53  *
     54  * RETURN    : None
     55  *
     56  * NOTE      : recvd_frame will be released after this call by caller, so if
     57  *             async operation needed for recvd_frame, it's our responsibility
     58  *             to save a copy for this variable to be used later.
     59  *==========================================================================*/
     60 void QCamera2HardwareInterface::zsl_channel_cb(mm_camera_super_buf_t *recvd_frame,
     61                                                void *userdata)
     62 {
     63     ATRACE_CALL();
     64     CDBG_HIGH("[KPI Perf] %s: E",__func__);
     65     char value[PROPERTY_VALUE_MAX];
     66     bool dump_raw = false;
     67     bool dump_yuv = false;
     68     bool log_matching = false;
     69     QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata;
     70     if (pme == NULL ||
     71         pme->mCameraHandle == NULL ||
     72         pme->mCameraHandle->camera_handle != recvd_frame->camera_handle){
     73        ALOGE("%s: camera obj not valid", __func__);
     74        return;
     75     }
     76 
     77     QCameraChannel *pChannel = pme->m_channels[QCAMERA_CH_TYPE_ZSL];
     78     if (pChannel == NULL ||
     79         pChannel->getMyHandle() != recvd_frame->ch_id) {
     80         ALOGE("%s: ZSL channel doesn't exist, return here", __func__);
     81         return;
     82     }
     83 
     84     if(pme->mParameters.isSceneSelectionEnabled() &&
     85             !pme->m_stateMachine.isCaptureRunning()) {
     86         pme->selectScene(pChannel, recvd_frame);
     87         pChannel->bufDone(recvd_frame);
     88         return;
     89     }
     90 
     91     CDBG_HIGH("%s: [ZSL Retro] Frame CB Unlock : %d, is AEC Locked: %d",
     92           __func__, recvd_frame->bUnlockAEC, pme->m_bLedAfAecLock);
     93     if(recvd_frame->bUnlockAEC && pme->m_bLedAfAecLock) {
     94         qcamera_sm_internal_evt_payload_t *payload =
     95                 (qcamera_sm_internal_evt_payload_t *)malloc(
     96                         sizeof(qcamera_sm_internal_evt_payload_t));
     97         if (NULL != payload) {
     98             memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
     99             payload->evt_type = QCAMERA_INTERNAL_EVT_RETRO_AEC_UNLOCK;
    100             int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
    101             if (rc != NO_ERROR) {
    102                 ALOGE("%s: processEvt for retro AEC unlock failed", __func__);
    103                 free(payload);
    104                 payload = NULL;
    105             }
    106         } else {
    107             ALOGE("%s: No memory for retro AEC event", __func__);
    108         }
    109     }
    110 
    111     // Check if retro-active frames are completed and camera is
    112     // ready to go ahead with LED estimation for regular frames
    113     if (recvd_frame->bReadyForPrepareSnapshot) {
    114       // Send an event
    115       CDBG_HIGH("%s: [ZSL Retro] Ready for Prepare Snapshot, signal ", __func__);
    116       qcamera_sm_internal_evt_payload_t *payload =
    117          (qcamera_sm_internal_evt_payload_t *)malloc(sizeof(qcamera_sm_internal_evt_payload_t));
    118       if (NULL != payload) {
    119         memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
    120         payload->evt_type = QCAMERA_INTERNAL_EVT_READY_FOR_SNAPSHOT;
    121         int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
    122         if (rc != NO_ERROR) {
    123           ALOGE("%s: processEvt Ready for Snaphot failed", __func__);
    124           free(payload);
    125           payload = NULL;
    126         }
    127       } else {
    128         ALOGE("%s: No memory for prepare signal event detect"
    129               " qcamera_sm_internal_evt_payload_t", __func__);
    130       }
    131     }
    132 
    133     /* indicate the parent that capture is done */
    134     pme->captureDone();
    135 
    136     // save a copy for the superbuf
    137     mm_camera_super_buf_t* frame =
    138                (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t));
    139     if (frame == NULL) {
    140         ALOGE("%s: Error allocating memory to save received_frame structure.", __func__);
    141         pChannel->bufDone(recvd_frame);
    142         return;
    143     }
    144     *frame = *recvd_frame;
    145 
    146     if (recvd_frame->num_bufs > 0) {
    147         ALOGI("[KPI Perf] %s: superbuf frame_idx %d", __func__,
    148             recvd_frame->bufs[0]->frame_idx);
    149     }
    150 
    151     // DUMP RAW if available
    152     property_get("persist.camera.zsl_raw", value, "0");
    153     dump_raw = atoi(value) > 0 ? true : false;
    154     if (dump_raw) {
    155         for (uint32_t i = 0; i < recvd_frame->num_bufs; i++) {
    156             if (recvd_frame->bufs[i]->stream_type == CAM_STREAM_TYPE_RAW) {
    157                 mm_camera_buf_def_t * raw_frame = recvd_frame->bufs[i];
    158                 QCameraStream *pStream = pChannel->getStreamByHandle(raw_frame->stream_id);
    159                 if (NULL != pStream) {
    160                     pme->dumpFrameToFile(pStream, raw_frame, QCAMERA_DUMP_FRM_RAW);
    161                 }
    162                 break;
    163             }
    164         }
    165     }
    166 
    167     // DUMP YUV before reprocess if needed
    168     property_get("persist.camera.zsl_yuv", value, "0");
    169     dump_yuv = atoi(value) > 0 ? true : false;
    170     if (dump_yuv) {
    171         for (uint32_t i = 0; i < recvd_frame->num_bufs; i++) {
    172             if (recvd_frame->bufs[i]->stream_type == CAM_STREAM_TYPE_SNAPSHOT) {
    173                 mm_camera_buf_def_t * yuv_frame = recvd_frame->bufs[i];
    174                 QCameraStream *pStream = pChannel->getStreamByHandle(yuv_frame->stream_id);
    175                 if (NULL != pStream) {
    176                     pme->dumpFrameToFile(pStream, yuv_frame, QCAMERA_DUMP_FRM_SNAPSHOT);
    177                 }
    178                 break;
    179             }
    180         }
    181     }
    182     //
    183     // whether need FD Metadata along with Snapshot frame in ZSL mode
    184     if(pme->needFDMetadata(QCAMERA_CH_TYPE_ZSL)){
    185         //Need Face Detection result for snapshot frames
    186         //Get the Meta Data frames
    187         mm_camera_buf_def_t *pMetaFrame = NULL;
    188         for (uint32_t i = 0; i < frame->num_bufs; i++) {
    189             QCameraStream *pStream = pChannel->getStreamByHandle(frame->bufs[i]->stream_id);
    190             if (pStream != NULL) {
    191                 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
    192                     pMetaFrame = frame->bufs[i]; //find the metadata
    193                     break;
    194                 }
    195             }
    196         }
    197 
    198         if(pMetaFrame != NULL){
    199             metadata_buffer_t *pMetaData = (metadata_buffer_t *)pMetaFrame->buffer;
    200             //send the face detection info
    201             uint8_t found = 0;
    202             cam_face_detection_data_t faces_data;
    203             IF_META_AVAILABLE(cam_face_detection_data_t, p_faces_data,
    204                     CAM_INTF_META_FACE_DETECTION, pMetaData) {
    205                 faces_data = *p_faces_data;
    206                 found = 1;
    207             } else {
    208                 memset(&faces_data, 0, sizeof(cam_face_detection_data_t));
    209             }
    210             faces_data.fd_type = QCAMERA_FD_SNAPSHOT; //HARD CODE here before MCT can support
    211             if(!found){
    212                 faces_data.num_faces_detected = 0;
    213             }else if(faces_data.num_faces_detected > MAX_ROI){
    214                 ALOGE("%s: Invalid number of faces %d",
    215                     __func__, faces_data.num_faces_detected);
    216             }
    217             qcamera_sm_internal_evt_payload_t *payload =
    218                 (qcamera_sm_internal_evt_payload_t *)malloc(sizeof(qcamera_sm_internal_evt_payload_t));
    219             if (NULL != payload) {
    220                 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
    221                 payload->evt_type = QCAMERA_INTERNAL_EVT_FACE_DETECT_RESULT;
    222                 payload->faces_data = faces_data;
    223                 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
    224                 if (rc != NO_ERROR) {
    225                     ALOGE("%s: processEvt face_detection_result failed", __func__);
    226                     free(payload);
    227                     payload = NULL;
    228                 }
    229             } else {
    230                 ALOGE("%s: No memory for face_detection_result qcamera_sm_internal_evt_payload_t", __func__);
    231             }
    232         }
    233     }
    234 
    235     property_get("persist.camera.dumpmetadata", value, "0");
    236     int32_t enabled = atoi(value);
    237     if (enabled) {
    238         mm_camera_buf_def_t *pMetaFrame = NULL;
    239         QCameraStream *pStream = NULL;
    240         for (uint32_t i = 0; i < frame->num_bufs; i++) {
    241             pStream = pChannel->getStreamByHandle(frame->bufs[i]->stream_id);
    242             if (pStream != NULL) {
    243                 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
    244                     pMetaFrame = frame->bufs[i];
    245                     if (pMetaFrame != NULL &&
    246                             ((metadata_buffer_t *)pMetaFrame->buffer)->is_tuning_params_valid) {
    247                         pme->dumpMetadataToFile(pStream, pMetaFrame, (char *) "ZSL_Snapshot");
    248                     }
    249                     break;
    250                 }
    251             }
    252         }
    253     }
    254 
    255     property_get("persist.camera.zsl_matching", value, "0");
    256     log_matching = atoi(value) > 0 ? true : false;
    257     if (log_matching) {
    258         CDBG_HIGH("%s : ZSL super buffer contains:", __func__);
    259         QCameraStream *pStream = NULL;
    260         for (uint32_t i = 0; i < frame->num_bufs; i++) {
    261             pStream = pChannel->getStreamByHandle(frame->bufs[i]->stream_id);
    262             if (pStream != NULL ) {
    263                 CDBG_HIGH("%s: Buffer with V4L index %d frame index %d of type %d Timestamp: %ld %ld ",
    264                         __func__,
    265                         frame->bufs[i]->buf_idx,
    266                         frame->bufs[i]->frame_idx,
    267                         pStream->getMyType(),
    268                         frame->bufs[i]->ts.tv_sec,
    269                         frame->bufs[i]->ts.tv_nsec);
    270             }
    271         }
    272     }
    273 
    274     // Wait on Postproc initialization if needed
    275     pme->waitDefferedWork(pme->mReprocJob);
    276 
    277     // send to postprocessor
    278     pme->m_postprocessor.processData(frame);
    279 
    280     CDBG_HIGH("[KPI Perf] %s: X", __func__);
    281 }
    282 
    283 /*===========================================================================
    284  * FUNCTION   : selectScene
    285  *
    286  * DESCRIPTION: send a preview callback when a specific selected scene is applied
    287  *
    288  * PARAMETERS :
    289  *   @pChannel: Camera channel
    290  *   @frame   : Bundled super buffer
    291  *
    292  * RETURN     : int32_t type of status
    293  *              NO_ERROR  -- success
    294  *              none-zero failure code
    295  *==========================================================================*/
    296 int32_t QCamera2HardwareInterface::selectScene(QCameraChannel *pChannel,
    297         mm_camera_super_buf_t *frame)
    298 {
    299     mm_camera_buf_def_t *pMetaFrame = NULL;
    300     QCameraStream *pStream = NULL;
    301     int32_t rc = NO_ERROR;
    302 
    303     if ((NULL == frame) || (NULL == pChannel)) {
    304         ALOGE("%s: Invalid scene select input", __func__);
    305         return BAD_VALUE;
    306     }
    307 
    308     cam_scene_mode_type selectedScene = mParameters.getSelectedScene();
    309     if (CAM_SCENE_MODE_MAX == selectedScene) {
    310         ALOGV("%s: No selected scene", __func__);
    311         return NO_ERROR;
    312     }
    313 
    314     for (uint32_t i = 0; i < frame->num_bufs; i++) {
    315         pStream = pChannel->getStreamByHandle(frame->bufs[i]->stream_id);
    316         if (pStream != NULL) {
    317             if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
    318                 pMetaFrame = frame->bufs[i];
    319                 break;
    320             }
    321         }
    322     }
    323 
    324     if (NULL == pMetaFrame) {
    325         ALOGE("%s: No metadata buffer found in scene select super buffer", __func__);
    326         return NO_INIT;
    327     }
    328 
    329     metadata_buffer_t *pMetaData = (metadata_buffer_t *)pMetaFrame->buffer;
    330 
    331     IF_META_AVAILABLE(cam_scene_mode_type, scene, CAM_INTF_META_CURRENT_SCENE, pMetaData) {
    332         if ((*scene == selectedScene) &&
    333                 (mDataCb != NULL) &&
    334                 (msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_FRAME) > 0)) {
    335             mm_camera_buf_def_t *preview_frame = NULL;
    336             for (uint32_t i = 0; i < frame->num_bufs; i++) {
    337                 pStream = pChannel->getStreamByHandle(frame->bufs[i]->stream_id);
    338                 if (pStream != NULL) {
    339                     if (pStream->isTypeOf(CAM_STREAM_TYPE_PREVIEW)) {
    340                         preview_frame = frame->bufs[i];
    341                         break;
    342                     }
    343                 }
    344             }
    345             if (preview_frame) {
    346                 QCameraGrallocMemory *memory = (QCameraGrallocMemory *)preview_frame->mem_info;
    347                 uint32_t idx = preview_frame->buf_idx;
    348                 rc = sendPreviewCallback(pStream, memory, idx);
    349                 if (NO_ERROR != rc) {
    350                     ALOGE("%s: Error triggering scene select preview callback", __func__);
    351                 } else {
    352                     mParameters.setSelectedScene(CAM_SCENE_MODE_MAX);
    353                 }
    354             } else {
    355                 ALOGE("%s: No preview buffer found in scene select super buffer", __func__);
    356                 return NO_INIT;
    357             }
    358         }
    359     } else {
    360         ALOGE("%s: No current scene metadata!", __func__);
    361         rc = NO_INIT;
    362     }
    363 
    364     return rc;
    365 }
    366 
    367 /*===========================================================================
    368  * FUNCTION   : capture_channel_cb_routine
    369  *
    370  * DESCRIPTION: helper function to handle snapshot superbuf callback directly from
    371  *              mm-camera-interface
    372  *
    373  * PARAMETERS :
    374  *   @recvd_frame : received super buffer
    375  *   @userdata    : user data ptr
    376  *
    377  * RETURN    : None
    378  *
    379  * NOTE      : recvd_frame will be released after this call by caller, so if
    380  *             async operation needed for recvd_frame, it's our responsibility
    381  *             to save a copy for this variable to be used later.
    382 *==========================================================================*/
    383 void QCamera2HardwareInterface::capture_channel_cb_routine(mm_camera_super_buf_t *recvd_frame,
    384                                                            void *userdata)
    385 {
    386     ATRACE_CALL();
    387     char value[PROPERTY_VALUE_MAX];
    388     CDBG_HIGH("[KPI Perf] %s: E PROFILE_YUV_CB_TO_HAL", __func__);
    389     QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata;
    390     if (pme == NULL ||
    391         pme->mCameraHandle == NULL ||
    392         pme->mCameraHandle->camera_handle != recvd_frame->camera_handle){
    393         ALOGE("%s: camera obj not valid", __func__);
    394         return;
    395     }
    396 
    397     QCameraChannel *pChannel = pme->m_channels[QCAMERA_CH_TYPE_CAPTURE];
    398     if (pChannel == NULL ||
    399         pChannel->getMyHandle() != recvd_frame->ch_id) {
    400         ALOGE("%s: Capture channel doesn't exist, return here", __func__);
    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         ALOGE("%s: Error allocating memory to save received_frame structure.", __func__);
    409         pChannel->bufDone(recvd_frame);
    410         return;
    411     }
    412     *frame = *recvd_frame;
    413 
    414     property_get("persist.camera.dumpmetadata", value, "0");
    415     int32_t enabled = atoi(value);
    416     if (enabled) {
    417         mm_camera_buf_def_t *pMetaFrame = NULL;
    418         QCameraStream *pStream = NULL;
    419         for (uint32_t i = 0; i < frame->num_bufs; i++) {
    420             pStream = pChannel->getStreamByHandle(frame->bufs[i]->stream_id);
    421             if (pStream != NULL) {
    422                 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
    423                     pMetaFrame = frame->bufs[i]; //find the metadata
    424                     if (pMetaFrame != NULL &&
    425                             ((metadata_buffer_t *)pMetaFrame->buffer)->is_tuning_params_valid) {
    426                         pme->dumpMetadataToFile(pStream, pMetaFrame, (char *) "Snapshot");
    427                     }
    428                     break;
    429                 }
    430             }
    431         }
    432     }
    433 
    434     // Wait on Postproc initialization if needed
    435     pme->waitDefferedWork(pme->mReprocJob);
    436 
    437     // send to postprocessor
    438     pme->m_postprocessor.processData(frame);
    439 
    440 /* START of test register face image for face authentication */
    441 #ifdef QCOM_TEST_FACE_REGISTER_FACE
    442     static uint8_t bRunFaceReg = 1;
    443 
    444     if (bRunFaceReg > 0) {
    445         // find snapshot frame
    446         QCameraStream *main_stream = NULL;
    447         mm_camera_buf_def_t *main_frame = NULL;
    448         for (int i = 0; i < recvd_frame->num_bufs; i++) {
    449             QCameraStream *pStream =
    450                 pChannel->getStreamByHandle(recvd_frame->bufs[i]->stream_id);
    451             if (pStream != NULL) {
    452                 if (pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT)) {
    453                     main_stream = pStream;
    454                     main_frame = recvd_frame->bufs[i];
    455                     break;
    456                 }
    457             }
    458         }
    459         if (main_stream != NULL && main_frame != NULL) {
    460             int32_t faceId = -1;
    461             cam_pp_offline_src_config_t config;
    462             memset(&config, 0, sizeof(cam_pp_offline_src_config_t));
    463             config.num_of_bufs = 1;
    464             main_stream->getFormat(config.input_fmt);
    465             main_stream->getFrameDimension(config.input_dim);
    466             main_stream->getFrameOffset(config.input_buf_planes.plane_info);
    467             CDBG_HIGH("DEBUG: registerFaceImage E");
    468             int32_t rc = pme->registerFaceImage(main_frame->buffer, &config, faceId);
    469             CDBG_HIGH("DEBUG: registerFaceImage X, ret=%d, faceId=%d", rc, faceId);
    470             bRunFaceReg = 0;
    471         }
    472     }
    473 
    474 #endif
    475 /* END of test register face image for face authentication */
    476 
    477     CDBG_HIGH("[KPI Perf] %s: X", __func__);
    478 }
    479 
    480 /*===========================================================================
    481  * FUNCTION   : postproc_channel_cb_routine
    482  *
    483  * DESCRIPTION: helper function to handle postprocess superbuf callback directly from
    484  *              mm-camera-interface
    485  *
    486  * PARAMETERS :
    487  *   @recvd_frame : received super buffer
    488  *   @userdata    : user data ptr
    489  *
    490  * RETURN    : None
    491  *
    492  * NOTE      : recvd_frame will be released after this call by caller, so if
    493  *             async operation needed for recvd_frame, it's our responsibility
    494  *             to save a copy for this variable to be used later.
    495 *==========================================================================*/
    496 void QCamera2HardwareInterface::postproc_channel_cb_routine(mm_camera_super_buf_t *recvd_frame,
    497                                                             void *userdata)
    498 {
    499     ATRACE_CALL();
    500     CDBG_HIGH("[KPI Perf] %s: E", __func__);
    501     QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata;
    502     if (pme == NULL ||
    503         pme->mCameraHandle == NULL ||
    504         pme->mCameraHandle->camera_handle != recvd_frame->camera_handle){
    505         ALOGE("%s: camera obj not valid", __func__);
    506         return;
    507     }
    508 
    509     // save a copy for the superbuf
    510     mm_camera_super_buf_t* frame =
    511                (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t));
    512     if (frame == NULL) {
    513         ALOGE("%s: Error allocating memory to save received_frame structure.", __func__);
    514         return;
    515     }
    516     *frame = *recvd_frame;
    517 
    518     // send to postprocessor
    519     pme->m_postprocessor.processPPData(frame);
    520 
    521     ATRACE_INT("Camera:Reprocess", 0);
    522     CDBG_HIGH("[KPI Perf] %s: X", __func__);
    523 }
    524 
    525 /*===========================================================================
    526  * FUNCTION   : preview_stream_cb_routine
    527  *
    528  * DESCRIPTION: helper function to handle preview frame from preview stream in
    529  *              normal case with display.
    530  *
    531  * PARAMETERS :
    532  *   @super_frame : received super buffer
    533  *   @stream      : stream object
    534  *   @userdata    : user data ptr
    535  *
    536  * RETURN    : None
    537  *
    538  * NOTE      : caller passes the ownership of super_frame, it's our
    539  *             responsibility to free super_frame once it's done. The new
    540  *             preview frame will be sent to display, and an older frame
    541  *             will be dequeued from display and needs to be returned back
    542  *             to kernel for future use.
    543  *==========================================================================*/
    544 void QCamera2HardwareInterface::preview_stream_cb_routine(mm_camera_super_buf_t *super_frame,
    545                                                           QCameraStream * stream,
    546                                                           void *userdata)
    547 {
    548     ATRACE_CALL();
    549     CDBG_HIGH("[KPI Perf] %s : BEGIN", __func__);
    550     int err = NO_ERROR;
    551     QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata;
    552     QCameraGrallocMemory *memory = (QCameraGrallocMemory *)super_frame->bufs[0]->mem_info;
    553 
    554     if (pme == NULL) {
    555         ALOGE("%s: Invalid hardware object", __func__);
    556         free(super_frame);
    557         return;
    558     }
    559     if (memory == NULL) {
    560         ALOGE("%s: Invalid memory object", __func__);
    561         free(super_frame);
    562         return;
    563     }
    564 
    565     mm_camera_buf_def_t *frame = super_frame->bufs[0];
    566     if (NULL == frame) {
    567         ALOGE("%s: preview frame is NLUL", __func__);
    568         free(super_frame);
    569         return;
    570     }
    571 
    572     if (!pme->needProcessPreviewFrame()) {
    573         ALOGE("%s: preview is not running, no need to process", __func__);
    574         stream->bufDone(frame->buf_idx);
    575         free(super_frame);
    576         return;
    577     }
    578 
    579     if (pme->needDebugFps()) {
    580         pme->debugShowPreviewFPS();
    581     }
    582 
    583     uint32_t idx = frame->buf_idx;
    584     pme->dumpFrameToFile(stream, frame, QCAMERA_DUMP_FRM_PREVIEW);
    585 
    586     if(pme->m_bPreviewStarted) {
    587        ALOGI("[KPI Perf] %s : PROFILE_FIRST_PREVIEW_FRAME", __func__);
    588        pme->m_bPreviewStarted = false ;
    589     }
    590 
    591     // Display the buffer.
    592     CDBG("%p displayBuffer %d E", pme, idx);
    593     int dequeuedIdx = memory->displayBuffer(idx);
    594     if (dequeuedIdx < 0 || dequeuedIdx >= memory->getCnt()) {
    595         CDBG_HIGH("%s: Invalid dequeued buffer index %d from display",
    596               __func__, dequeuedIdx);
    597     } else {
    598         // Return dequeued buffer back to driver
    599         err = stream->bufDone((uint32_t)dequeuedIdx);
    600         if ( err < 0) {
    601             ALOGE("stream bufDone failed %d", err);
    602         }
    603     }
    604 
    605     // Handle preview data callback
    606     if (pme->mDataCb != NULL &&
    607             (pme->msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_FRAME) > 0) &&
    608             (!pme->mParameters.isSceneSelectionEnabled())) {
    609         int32_t rc = pme->sendPreviewCallback(stream, memory, idx);
    610         if (NO_ERROR != rc) {
    611             ALOGE("%s: Preview callback was not sent succesfully", __func__);
    612         }
    613     }
    614 
    615     free(super_frame);
    616     CDBG_HIGH("[KPI Perf] %s : END", __func__);
    617     return;
    618 }
    619 
    620 /*===========================================================================
    621  * FUNCTION   : sendPreviewCallback
    622  *
    623  * DESCRIPTION: helper function for triggering preview callbacks
    624  *
    625  * PARAMETERS :
    626  *   @stream    : stream object
    627  *   @memory    : Gralloc memory allocator
    628  *   @idx       : buffer index
    629  *
    630  * RETURN     : int32_t type of status
    631  *              NO_ERROR  -- success
    632  *              none-zero failure code
    633  *==========================================================================*/
    634 int32_t QCamera2HardwareInterface::sendPreviewCallback(QCameraStream *stream,
    635         QCameraGrallocMemory *memory, uint32_t idx)
    636 {
    637     camera_memory_t *previewMem = NULL;
    638     camera_memory_t *data = NULL;
    639     camera_memory_t *dataToApp = NULL;
    640     size_t previewBufSize = 0;
    641     size_t previewBufSizeFromCallback = 0;
    642     cam_dimension_t preview_dim;
    643     cam_format_t previewFmt;
    644     int32_t rc = NO_ERROR;
    645     int32_t yStride = 0;
    646     int32_t yScanline = 0;
    647     int32_t uvStride = 0;
    648     int32_t uvScanline = 0;
    649     int32_t uStride = 0;
    650     int32_t uScanline = 0;
    651     int32_t vStride = 0;
    652     int32_t vScanline = 0;
    653     int32_t yStrideToApp = 0;
    654     int32_t uvStrideToApp = 0;
    655     int32_t yScanlineToApp = 0;
    656     int32_t uvScanlineToApp = 0;
    657     int32_t srcOffset = 0;
    658     int32_t dstOffset = 0;
    659     int32_t srcBaseOffset = 0;
    660     int32_t dstBaseOffset = 0;
    661     int i;
    662 
    663     if ((NULL == stream) || (NULL == memory)) {
    664         ALOGE("%s: Invalid preview callback input", __func__);
    665         return BAD_VALUE;
    666     }
    667 
    668     cam_stream_info_t *streamInfo =
    669             reinterpret_cast<cam_stream_info_t *>(stream->getStreamInfoBuf()->getPtr(0));
    670     if (NULL == streamInfo) {
    671         ALOGE("%s: Invalid streamInfo", __func__);
    672         return BAD_VALUE;
    673     }
    674 
    675     stream->getFrameDimension(preview_dim);
    676     stream->getFormat(previewFmt);
    677 
    678     /* The preview buffer size in the callback should be
    679      * (width*height*bytes_per_pixel). As all preview formats we support,
    680      * use 12 bits per pixel, buffer size = previewWidth * previewHeight * 3/2.
    681      * We need to put a check if some other formats are supported in future. */
    682     if ((previewFmt == CAM_FORMAT_YUV_420_NV21) ||
    683         (previewFmt == CAM_FORMAT_YUV_420_NV12) ||
    684         (previewFmt == CAM_FORMAT_YUV_420_YV12)) {
    685         if(previewFmt == CAM_FORMAT_YUV_420_YV12) {
    686             yStride = streamInfo->buf_planes.plane_info.mp[0].stride;
    687             yScanline = streamInfo->buf_planes.plane_info.mp[0].scanline;
    688             uStride = streamInfo->buf_planes.plane_info.mp[1].stride;
    689             uScanline = streamInfo->buf_planes.plane_info.mp[1].scanline;
    690             vStride = streamInfo->buf_planes.plane_info.mp[2].stride;
    691             vScanline = streamInfo->buf_planes.plane_info.mp[2].scanline;
    692 
    693             previewBufSize = (size_t)
    694                     (yStride * yScanline + uStride * uScanline + vStride * vScanline);
    695             previewBufSizeFromCallback = previewBufSize;
    696         } else {
    697             yStride = streamInfo->buf_planes.plane_info.mp[0].stride;
    698             yScanline = streamInfo->buf_planes.plane_info.mp[0].scanline;
    699             uvStride = streamInfo->buf_planes.plane_info.mp[1].stride;
    700             uvScanline = streamInfo->buf_planes.plane_info.mp[1].scanline;
    701 
    702             yStrideToApp = preview_dim.width;
    703             yScanlineToApp = preview_dim.height;
    704             uvStrideToApp = yStrideToApp;
    705             uvScanlineToApp = yScanlineToApp / 2;
    706 
    707             previewBufSize = (size_t)
    708                     ((yStrideToApp * yScanlineToApp) + (uvStrideToApp * uvScanlineToApp));
    709 
    710             previewBufSizeFromCallback = (size_t)
    711                     ((yStride * yScanline) + (uvStride * uvScanline));
    712         }
    713         if(previewBufSize == previewBufSizeFromCallback) {
    714             previewMem = mGetMemory(memory->getFd(idx),
    715                        previewBufSize, 1, mCallbackCookie);
    716             if (!previewMem || !previewMem->data) {
    717                 ALOGE("%s: mGetMemory failed.\n", __func__);
    718                 return NO_MEMORY;
    719             } else {
    720                 data = previewMem;
    721             }
    722         } else {
    723             data = memory->getMemory(idx, false);
    724             dataToApp = mGetMemory(-1, previewBufSize, 1, mCallbackCookie);
    725             if (!dataToApp || !dataToApp->data) {
    726                 ALOGE("%s: mGetMemory failed.\n", __func__);
    727                 return NO_MEMORY;
    728             }
    729 
    730             for (i = 0; i < preview_dim.height; i++) {
    731                 srcOffset = i * yStride;
    732                 dstOffset = i * yStrideToApp;
    733 
    734                 memcpy((unsigned char *) dataToApp->data + dstOffset,
    735                         (unsigned char *) data->data + srcOffset,
    736                         (size_t)yStrideToApp);
    737             }
    738 
    739             srcBaseOffset = yStride * yScanline;
    740             dstBaseOffset = yStrideToApp * yScanlineToApp;
    741 
    742             for (i = 0; i < preview_dim.height/2; i++) {
    743                 srcOffset = i * uvStride + srcBaseOffset;
    744                 dstOffset = i * uvStrideToApp + dstBaseOffset;
    745 
    746                 memcpy((unsigned char *) dataToApp->data + dstOffset,
    747                         (unsigned char *) data->data + srcOffset,
    748                         (size_t)yStrideToApp);
    749             }
    750         }
    751     } else {
    752         data = memory->getMemory(idx, false);
    753         ALOGE("%s: Invalid preview format, buffer size in preview callback may be wrong.",
    754                 __func__);
    755     }
    756     qcamera_callback_argm_t cbArg;
    757     memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
    758     cbArg.cb_type = QCAMERA_DATA_CALLBACK;
    759     cbArg.msg_type = CAMERA_MSG_PREVIEW_FRAME;
    760     if (previewBufSize != 0 && previewBufSizeFromCallback != 0 &&
    761             previewBufSize == previewBufSizeFromCallback) {
    762         cbArg.data = data;
    763     } else {
    764         cbArg.data = dataToApp;
    765     }
    766     if ( previewMem ) {
    767         cbArg.user_data = previewMem;
    768         cbArg.release_cb = releaseCameraMemory;
    769     } else if (dataToApp) {
    770         cbArg.user_data = dataToApp;
    771         cbArg.release_cb = releaseCameraMemory;
    772     }
    773     cbArg.cookie = this;
    774     rc = m_cbNotifier.notifyCallback(cbArg);
    775     if (rc != NO_ERROR) {
    776         ALOGE("%s: fail sending notification", __func__);
    777         if (previewMem) {
    778             previewMem->release(previewMem);
    779         } else if (dataToApp) {
    780             dataToApp->release(dataToApp);
    781         }
    782     }
    783 
    784     return rc;
    785 }
    786 
    787 /*===========================================================================
    788  * FUNCTION   : nodisplay_preview_stream_cb_routine
    789  *
    790  * DESCRIPTION: helper function to handle preview frame from preview stream in
    791  *              no-display case
    792  *
    793  * PARAMETERS :
    794  *   @super_frame : received super buffer
    795  *   @stream      : stream object
    796  *   @userdata    : user data ptr
    797  *
    798  * RETURN    : None
    799  *
    800  * NOTE      : caller passes the ownership of super_frame, it's our
    801  *             responsibility to free super_frame once it's done.
    802  *==========================================================================*/
    803 void QCamera2HardwareInterface::nodisplay_preview_stream_cb_routine(
    804                                                           mm_camera_super_buf_t *super_frame,
    805                                                           QCameraStream *stream,
    806                                                           void * userdata)
    807 {
    808     ATRACE_CALL();
    809     CDBG_HIGH("[KPI Perf] %s E",__func__);
    810     QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata;
    811     if (pme == NULL ||
    812         pme->mCameraHandle == NULL ||
    813         pme->mCameraHandle->camera_handle != super_frame->camera_handle){
    814         ALOGE("%s: camera obj not valid", __func__);
    815         // simply free super frame
    816         free(super_frame);
    817         return;
    818     }
    819     mm_camera_buf_def_t *frame = super_frame->bufs[0];
    820     if (NULL == frame) {
    821         ALOGE("%s: preview frame is NULL", __func__);
    822         free(super_frame);
    823         return;
    824     }
    825 
    826     if (!pme->needProcessPreviewFrame()) {
    827         CDBG_HIGH("%s: preview is not running, no need to process", __func__);
    828         stream->bufDone(frame->buf_idx);
    829         free(super_frame);
    830         return;
    831     }
    832 
    833     if (pme->needDebugFps()) {
    834         pme->debugShowPreviewFPS();
    835     }
    836 
    837     QCameraMemory *previewMemObj = (QCameraMemory *)frame->mem_info;
    838     camera_memory_t *preview_mem = NULL;
    839     if (previewMemObj != NULL) {
    840         preview_mem = previewMemObj->getMemory(frame->buf_idx, false);
    841     }
    842     if (NULL != previewMemObj && NULL != preview_mem) {
    843         pme->dumpFrameToFile(stream, frame, QCAMERA_DUMP_FRM_PREVIEW);
    844 
    845         if (pme->needProcessPreviewFrame() &&
    846             pme->mDataCb != NULL &&
    847             pme->msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_FRAME) > 0 ) {
    848             qcamera_callback_argm_t cbArg;
    849             memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
    850             cbArg.cb_type = QCAMERA_DATA_CALLBACK;
    851             cbArg.msg_type = CAMERA_MSG_PREVIEW_FRAME;
    852             cbArg.data = preview_mem;
    853             cbArg.user_data = (void *) &frame->buf_idx;
    854             cbArg.cookie = stream;
    855             cbArg.release_cb = returnStreamBuffer;
    856             int32_t rc = pme->m_cbNotifier.notifyCallback(cbArg);
    857             if (rc != NO_ERROR) {
    858                 ALOGE("%s: fail sending data notify", __func__);
    859                 stream->bufDone(frame->buf_idx);
    860             }
    861         } else {
    862             stream->bufDone(frame->buf_idx);
    863         }
    864     }
    865     free(super_frame);
    866     CDBG_HIGH("[KPI Perf] %s X",__func__);
    867 }
    868 
    869 /*===========================================================================
    870  * FUNCTION   : rdi_mode_stream_cb_routine
    871  *
    872  * DESCRIPTION: helper function to handle RDI frame from preview stream in
    873  *              rdi mode case
    874  *
    875  * PARAMETERS :
    876  *   @super_frame : received super buffer
    877  *   @stream      : stream object
    878  *   @userdata    : user data ptr
    879  *
    880  * RETURN    : None
    881  *
    882  * NOTE      : caller passes the ownership of super_frame, it's our
    883  *             responsibility to free super_frame once it's done.
    884  *==========================================================================*/
    885 void QCamera2HardwareInterface::rdi_mode_stream_cb_routine(
    886   mm_camera_super_buf_t *super_frame,
    887   QCameraStream *stream,
    888   void * userdata)
    889 {
    890     ATRACE_CALL();
    891     CDBG_HIGH("RDI_DEBUG %s[%d]: Enter", __func__, __LINE__);
    892     QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata;
    893     if (pme == NULL ||
    894         pme->mCameraHandle == NULL ||
    895         pme->mCameraHandle->camera_handle != super_frame->camera_handle){
    896         ALOGE("%s: camera obj not valid", __func__);
    897         free(super_frame);
    898         return;
    899     }
    900     mm_camera_buf_def_t *frame = super_frame->bufs[0];
    901     if (NULL == frame) {
    902         ALOGE("%s: preview frame is NLUL", __func__);
    903         goto end;
    904     }
    905     if (!pme->needProcessPreviewFrame()) {
    906         ALOGE("%s: preview is not running, no need to process", __func__);
    907         stream->bufDone(frame->buf_idx);
    908         goto end;
    909     }
    910     if (pme->needDebugFps()) {
    911         pme->debugShowPreviewFPS();
    912     }
    913     // Non-secure Mode
    914     if (!pme->isSecureMode()) {
    915         QCameraMemory *previewMemObj = (QCameraMemory *)frame->mem_info;
    916         if (NULL == previewMemObj) {
    917             ALOGE("%s: previewMemObj is NULL", __func__);
    918             stream->bufDone(frame->buf_idx);
    919             goto end;
    920         }
    921 
    922         camera_memory_t *preview_mem = previewMemObj->getMemory(frame->buf_idx, false);
    923         if (NULL != preview_mem) {
    924             previewMemObj->cleanCache(frame->buf_idx);
    925             // Dump RAW frame
    926             pme->dumpFrameToFile(stream, frame, QCAMERA_DUMP_FRM_RAW);
    927             // Notify Preview callback frame
    928             if (pme->needProcessPreviewFrame() &&
    929                     pme->mDataCb != NULL &&
    930                     pme->msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_FRAME) > 0) {
    931                 qcamera_callback_argm_t cbArg;
    932                 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
    933                 cbArg.cb_type    = QCAMERA_DATA_CALLBACK;
    934                 cbArg.msg_type   = CAMERA_MSG_PREVIEW_FRAME;
    935                 cbArg.data       = preview_mem;
    936                 cbArg.user_data = (void *) &frame->buf_idx;
    937                 cbArg.cookie     = stream;
    938                 cbArg.release_cb = returnStreamBuffer;
    939                 pme->m_cbNotifier.notifyCallback(cbArg);
    940             } else {
    941                 ALOGE("%s: preview_mem is NULL", __func__);
    942                 stream->bufDone(frame->buf_idx);
    943             }
    944         }
    945         else {
    946             ALOGE("%s: preview_mem is NULL", __func__);
    947             stream->bufDone(frame->buf_idx);
    948         }
    949     } else {
    950         // Secure Mode
    951         // We will do QCAMERA_NOTIFY_CALLBACK and share FD in case of secure mode
    952         QCameraMemory *previewMemObj = (QCameraMemory *)frame->mem_info;
    953         if (NULL == previewMemObj) {
    954             ALOGE("%s: previewMemObj is NULL", __func__);
    955             stream->bufDone(frame->buf_idx);
    956             goto end;
    957         }
    958 
    959         int fd = previewMemObj->getFd(frame->buf_idx);
    960         ALOGD("%s: Preview frame fd =%d for index = %d ", __func__, fd, frame->buf_idx);
    961         if (pme->needProcessPreviewFrame() &&
    962                 pme->mDataCb != NULL &&
    963                 pme->msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_FRAME) > 0) {
    964             // Prepare Callback structure
    965             qcamera_callback_argm_t cbArg;
    966             memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
    967             cbArg.cb_type    = QCAMERA_NOTIFY_CALLBACK;
    968             cbArg.msg_type   = CAMERA_MSG_PREVIEW_FRAME;
    969 #ifndef VANILLA_HAL
    970             cbArg.ext1       = CAMERA_FRAME_DATA_FD;
    971             cbArg.ext2       = fd;
    972 #endif
    973             cbArg.user_data  = (void *) &frame->buf_idx;
    974             cbArg.cookie     = stream;
    975             cbArg.release_cb = returnStreamBuffer;
    976             pme->m_cbNotifier.notifyCallback(cbArg);
    977         } else {
    978             CDBG_HIGH("%s: No need to process preview frame, return buffer", __func__);
    979             stream->bufDone(frame->buf_idx);
    980         }
    981     }
    982 end:
    983     free(super_frame);
    984     CDBG_HIGH("RDI_DEBUG %s[%d]: Exit", __func__, __LINE__);
    985     return;
    986 }
    987 
    988 /*===========================================================================
    989  * FUNCTION   : postview_stream_cb_routine
    990  *
    991  * DESCRIPTION: helper function to handle post frame from postview stream
    992  *
    993  * PARAMETERS :
    994  *   @super_frame : received super buffer
    995  *   @stream      : stream object
    996  *   @userdata    : user data ptr
    997  *
    998  * RETURN    : None
    999  *
   1000  * NOTE      : caller passes the ownership of super_frame, it's our
   1001  *             responsibility to free super_frame once it's done.
   1002  *==========================================================================*/
   1003 void QCamera2HardwareInterface::postview_stream_cb_routine(mm_camera_super_buf_t *super_frame,
   1004                                                            QCameraStream *stream,
   1005                                                            void *userdata)
   1006 {
   1007     ATRACE_CALL();
   1008     int err = NO_ERROR;
   1009     QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata;
   1010     QCameraGrallocMemory *memory = (QCameraGrallocMemory *)super_frame->bufs[0]->mem_info;
   1011 
   1012     if (pme == NULL) {
   1013         ALOGE("%s: Invalid hardware object", __func__);
   1014         free(super_frame);
   1015         return;
   1016     }
   1017     if (memory == NULL) {
   1018         ALOGE("%s: Invalid memory object", __func__);
   1019         free(super_frame);
   1020         return;
   1021     }
   1022 
   1023     CDBG_HIGH("[KPI Perf] %s : BEGIN", __func__);
   1024 
   1025     mm_camera_buf_def_t *frame = super_frame->bufs[0];
   1026     if (NULL == frame) {
   1027         ALOGE("%s: preview frame is NULL", __func__);
   1028         free(super_frame);
   1029         return;
   1030     }
   1031 
   1032     QCameraMemory *memObj = (QCameraMemory *)frame->mem_info;
   1033     if (NULL != memObj) {
   1034         pme->dumpFrameToFile(stream, frame, QCAMERA_DUMP_FRM_THUMBNAIL);
   1035     }
   1036 
   1037     // Return buffer back to driver
   1038     err = stream->bufDone(frame->buf_idx);
   1039     if ( err < 0) {
   1040         ALOGE("stream bufDone failed %d", err);
   1041     }
   1042 
   1043     free(super_frame);
   1044     CDBG_HIGH("[KPI Perf] %s : END", __func__);
   1045     return;
   1046 }
   1047 
   1048 /*===========================================================================
   1049  * FUNCTION   : video_stream_cb_routine
   1050  *
   1051  * DESCRIPTION: helper function to handle video frame from video stream
   1052  *
   1053  * PARAMETERS :
   1054  *   @super_frame : received super buffer
   1055  *   @stream      : stream object
   1056  *   @userdata    : user data ptr
   1057  *
   1058  * RETURN    : None
   1059  *
   1060  * NOTE      : caller passes the ownership of super_frame, it's our
   1061  *             responsibility to free super_frame once it's done. video
   1062  *             frame will be sent to video encoder. Once video encoder is
   1063  *             done with the video frame, it will call another API
   1064  *             (release_recording_frame) to return the frame back
   1065  *==========================================================================*/
   1066 void QCamera2HardwareInterface::video_stream_cb_routine(mm_camera_super_buf_t *super_frame,
   1067                                                         QCameraStream *stream,
   1068                                                         void *userdata)
   1069 {
   1070     ATRACE_CALL();
   1071     CDBG_HIGH("[KPI Perf] %s : BEGIN", __func__);
   1072     QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata;
   1073     if (pme == NULL ||
   1074         pme->mCameraHandle == NULL ||
   1075         pme->mCameraHandle->camera_handle != super_frame->camera_handle){
   1076         ALOGE("%s: camera obj not valid", __func__);
   1077         // simply free super frame
   1078         free(super_frame);
   1079         return;
   1080     }
   1081 
   1082     mm_camera_buf_def_t *frame = super_frame->bufs[0];
   1083 
   1084     if (pme->needDebugFps()) {
   1085         pme->debugShowVideoFPS();
   1086     }
   1087     if(pme->m_bRecordStarted) {
   1088        ALOGI("[KPI Perf] %s : PROFILE_FIRST_RECORD_FRAME", __func__);
   1089        pme->m_bRecordStarted = false ;
   1090     }
   1091     CDBG_HIGH("%s: Stream(%d), Timestamp: %ld %ld",
   1092           __func__,
   1093           frame->stream_id,
   1094           frame->ts.tv_sec,
   1095           frame->ts.tv_nsec);
   1096 
   1097     if (frame->buf_type == CAM_STREAM_BUF_TYPE_MPLANE) {
   1098         nsecs_t timeStamp;
   1099         timeStamp = nsecs_t(frame->ts.tv_sec) * 1000000000LL + frame->ts.tv_nsec;
   1100         CDBG_HIGH("Send Video frame to services/encoder TimeStamp : %lld",
   1101             timeStamp);
   1102         QCameraMemory *videoMemObj = (QCameraMemory *)frame->mem_info;
   1103         camera_memory_t *video_mem = NULL;
   1104         if (NULL != videoMemObj) {
   1105             video_mem = videoMemObj->getMemory(frame->buf_idx,
   1106                     (pme->mStoreMetaDataInFrame > 0)? true : false);
   1107         }
   1108         if (NULL != videoMemObj && NULL != video_mem) {
   1109             pme->dumpFrameToFile(stream, frame, QCAMERA_DUMP_FRM_VIDEO);
   1110             if ((pme->mDataCbTimestamp != NULL) &&
   1111                 pme->msgTypeEnabledWithLock(CAMERA_MSG_VIDEO_FRAME) > 0) {
   1112                 qcamera_callback_argm_t cbArg;
   1113                 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
   1114                 cbArg.cb_type = QCAMERA_DATA_TIMESTAMP_CALLBACK;
   1115                 cbArg.msg_type = CAMERA_MSG_VIDEO_FRAME;
   1116                 cbArg.data = video_mem;
   1117                 cbArg.timestamp = timeStamp;
   1118                 int32_t rc = pme->m_cbNotifier.notifyCallback(cbArg);
   1119                 if (rc != NO_ERROR) {
   1120                     ALOGE("%s: fail sending data notify", __func__);
   1121                     stream->bufDone(frame->buf_idx);
   1122                 }
   1123             }
   1124         }
   1125     } else {
   1126         QCameraMemory *videoMemObj = (QCameraMemory *)frame->mem_info;
   1127         camera_memory_t *video_mem = NULL;
   1128         native_handle_t *nh = NULL;
   1129         int fd_cnt = frame->user_buf.bufs_used;
   1130         if (NULL != videoMemObj) {
   1131             video_mem = videoMemObj->getMemory(frame->buf_idx, true);
   1132             if (video_mem != NULL) {
   1133                 struct encoder_media_buffer_type * packet =
   1134                         (struct encoder_media_buffer_type *)video_mem->data;
   1135                 // fd cnt => Number of buffer FD's and buffer for offset, size, timestamp
   1136                 packet->meta_handle = native_handle_create(fd_cnt, (3 * fd_cnt));
   1137                 packet->buffer_type = kMetadataBufferTypeCameraSource;
   1138                 nh = const_cast<native_handle_t *>(packet->meta_handle);
   1139             } else {
   1140                 ALOGE("%s video_mem NULL", __func__);
   1141             }
   1142         } else {
   1143             ALOGE("%s videoMemObj NULL", __func__);
   1144         }
   1145 
   1146         if (nh != NULL) {
   1147             nsecs_t timeStamp;
   1148             timeStamp = nsecs_t(frame->ts.tv_sec) * 1000000000LL
   1149                     + frame->ts.tv_nsec;
   1150             CDBG("Batch buffer TimeStamp : %lld FD = %d index = %d fd_cnt = %d",
   1151                     timeStamp, frame->fd, frame->buf_idx, fd_cnt);
   1152 
   1153             for (int i = 0; i < fd_cnt; i++) {
   1154                 if (frame->user_buf.buf_idx[i] >= 0) {
   1155                     mm_camera_buf_def_t *plane_frame =
   1156                             &frame->user_buf.plane_buf[frame->user_buf.buf_idx[i]];
   1157                     QCameraMemory *frameobj = (QCameraMemory *)plane_frame->mem_info;
   1158                     nsecs_t frame_ts = nsecs_t(plane_frame->ts.tv_sec) * 1000000000LL
   1159                             + plane_frame->ts.tv_nsec;
   1160                     /*data[0] => FD data[1] => OFFSET data[2] => SIZE data[3] => TIMESTAMP*/
   1161                     nh->data[i] = frameobj->getFd(plane_frame->buf_idx);
   1162                     nh->data[fd_cnt + i] = 0;
   1163                     nh->data[(2 * fd_cnt) + i] = (int)frameobj->getSize(plane_frame->buf_idx);
   1164                     nh->data[(3 * fd_cnt) + i] = (int)(frame_ts - timeStamp);
   1165                     CDBG("Send Video frames to services/encoder delta : %lld FD = %d index = %d",
   1166                             (frame_ts - timeStamp), plane_frame->fd, plane_frame->buf_idx);
   1167                     pme->dumpFrameToFile(stream, plane_frame, QCAMERA_DUMP_FRM_VIDEO);
   1168                 }
   1169             }
   1170 
   1171             if ((pme->mDataCbTimestamp != NULL) &&
   1172                         pme->msgTypeEnabledWithLock(CAMERA_MSG_VIDEO_FRAME) > 0) {
   1173                 qcamera_callback_argm_t cbArg;
   1174                 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
   1175                 cbArg.cb_type = QCAMERA_DATA_TIMESTAMP_CALLBACK;
   1176                 cbArg.msg_type = CAMERA_MSG_VIDEO_FRAME;
   1177                 cbArg.data = video_mem;
   1178                 cbArg.timestamp = timeStamp;
   1179                 int32_t rc = pme->m_cbNotifier.notifyCallback(cbArg);
   1180                 if (rc != NO_ERROR) {
   1181                     ALOGE("%s: fail sending data notify", __func__);
   1182                     stream->bufDone(frame->buf_idx);
   1183                 }
   1184             }
   1185         } else {
   1186             ALOGE("%s: No Video Meta Available. Return Buffer", __func__);
   1187             stream->bufDone(super_frame->bufs[0]->buf_idx);
   1188         }
   1189     }
   1190     free(super_frame);
   1191     CDBG_HIGH("[KPI Perf] %s : END", __func__);
   1192 }
   1193 
   1194 /*===========================================================================
   1195  * FUNCTION   : snapshot_channel_cb_routine
   1196  *
   1197  * DESCRIPTION: helper function to handle snapshot frame from snapshot channel
   1198  *
   1199  * PARAMETERS :
   1200  *   @super_frame : received super buffer
   1201  *   @userdata    : user data ptr
   1202  *
   1203  * RETURN    : None
   1204  *
   1205  * NOTE      : recvd_frame will be released after this call by caller, so if
   1206  *             async operation needed for recvd_frame, it's our responsibility
   1207  *             to save a copy for this variable to be used later.
   1208  *==========================================================================*/
   1209 void QCamera2HardwareInterface::snapshot_channel_cb_routine(mm_camera_super_buf_t *super_frame,
   1210        void *userdata)
   1211 {
   1212     ATRACE_CALL();
   1213     char value[PROPERTY_VALUE_MAX];
   1214 
   1215     CDBG_HIGH("[KPI Perf] %s: E", __func__);
   1216     QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata;
   1217     if (pme == NULL ||
   1218         pme->mCameraHandle == NULL ||
   1219         pme->mCameraHandle->camera_handle != super_frame->camera_handle){
   1220         ALOGE("%s: camera obj not valid", __func__);
   1221         // simply free super frame
   1222         free(super_frame);
   1223         return;
   1224     }
   1225 
   1226     QCameraChannel *pChannel = pme->m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
   1227     if ((pChannel == NULL) || (pChannel->getMyHandle() != super_frame->ch_id)) {
   1228         ALOGE("%s: Snapshot channel doesn't exist, return here", __func__);
   1229         return;
   1230     }
   1231 
   1232     property_get("persist.camera.dumpmetadata", value, "0");
   1233     int32_t enabled = atoi(value);
   1234     if (enabled) {
   1235         if (pChannel == NULL ||
   1236             pChannel->getMyHandle() != super_frame->ch_id) {
   1237             ALOGE("%s: Capture channel doesn't exist, return here", __func__);
   1238             return;
   1239         }
   1240         mm_camera_buf_def_t *pMetaFrame = NULL;
   1241         QCameraStream *pStream = NULL;
   1242         for (uint32_t i = 0; i < super_frame->num_bufs; i++) {
   1243             pStream = pChannel->getStreamByHandle(super_frame->bufs[i]->stream_id);
   1244             if (pStream != NULL) {
   1245                 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
   1246                     pMetaFrame = super_frame->bufs[i]; //find the metadata
   1247                     if (pMetaFrame != NULL &&
   1248                             ((metadata_buffer_t *)pMetaFrame->buffer)->is_tuning_params_valid) {
   1249                         pme->dumpMetadataToFile(pStream, pMetaFrame, (char *) "Snapshot");
   1250                     }
   1251                     break;
   1252                 }
   1253             }
   1254         }
   1255     }
   1256 
   1257     // save a copy for the superbuf
   1258     mm_camera_super_buf_t* frame = (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t));
   1259     if (frame == NULL) {
   1260         ALOGE("%s: Error allocating memory to save received_frame structure.",
   1261                 __func__);
   1262         pChannel->bufDone(super_frame);
   1263         return;
   1264     }
   1265     *frame = *super_frame;
   1266 
   1267     pme->m_postprocessor.processData(frame);
   1268 
   1269     CDBG_HIGH("[KPI Perf] %s: X", __func__);
   1270 }
   1271 
   1272 /*===========================================================================
   1273  * FUNCTION   : raw_stream_cb_routine
   1274  *
   1275  * DESCRIPTION: helper function to handle raw dump frame from raw stream
   1276  *
   1277  * PARAMETERS :
   1278  *   @super_frame : received super buffer
   1279  *   @stream      : stream object
   1280  *   @userdata    : user data ptr
   1281  *
   1282  * RETURN    : None
   1283  *
   1284  * NOTE      : caller passes the ownership of super_frame, it's our
   1285  *             responsibility to free super_frame once it's done. For raw
   1286  *             frame, there is no need to send to postprocessor for jpeg
   1287  *             encoding. this function will play shutter and send the data
   1288  *             callback to upper layer. Raw frame buffer will be returned
   1289  *             back to kernel, and frame will be free after use.
   1290  *==========================================================================*/
   1291 void QCamera2HardwareInterface::raw_stream_cb_routine(mm_camera_super_buf_t * super_frame,
   1292                                                       QCameraStream * /*stream*/,
   1293                                                       void * userdata)
   1294 {
   1295     ATRACE_CALL();
   1296     CDBG_HIGH("[KPI Perf] %s : BEGIN", __func__);
   1297     QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata;
   1298     if (pme == NULL ||
   1299         pme->mCameraHandle == NULL ||
   1300         pme->mCameraHandle->camera_handle != super_frame->camera_handle){
   1301         ALOGE("%s: camera obj not valid", __func__);
   1302         // simply free super frame
   1303         free(super_frame);
   1304         return;
   1305     }
   1306 
   1307     pme->m_postprocessor.processRawData(super_frame);
   1308     CDBG_HIGH("[KPI Perf] %s : END", __func__);
   1309 }
   1310 
   1311 /*===========================================================================
   1312  * FUNCTION   : preview_raw_stream_cb_routine
   1313  *
   1314  * DESCRIPTION: helper function to handle raw frame during standard preview
   1315  *
   1316  * PARAMETERS :
   1317  *   @super_frame : received super buffer
   1318  *   @stream      : stream object
   1319  *   @userdata    : user data ptr
   1320  *
   1321  * RETURN    : None
   1322  *
   1323  * NOTE      : caller passes the ownership of super_frame, it's our
   1324  *             responsibility to free super_frame once it's done.
   1325  *==========================================================================*/
   1326 void QCamera2HardwareInterface::preview_raw_stream_cb_routine(mm_camera_super_buf_t * super_frame,
   1327                                                               QCameraStream * stream,
   1328                                                               void * userdata)
   1329 {
   1330     ATRACE_CALL();
   1331     CDBG_HIGH("[KPI Perf] %s : BEGIN", __func__);
   1332     char value[PROPERTY_VALUE_MAX];
   1333     bool dump_raw = false;
   1334 
   1335     QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata;
   1336     if (pme == NULL ||
   1337         pme->mCameraHandle == NULL ||
   1338         pme->mCameraHandle->camera_handle != super_frame->camera_handle){
   1339         ALOGE("%s: camera obj not valid", __func__);
   1340         // simply free super frame
   1341         free(super_frame);
   1342         return;
   1343     }
   1344 
   1345     property_get("persist.camera.preview_raw", value, "0");
   1346     dump_raw = atoi(value) > 0 ? true : false;
   1347 
   1348     for (uint32_t i = 0; i < super_frame->num_bufs; i++) {
   1349         if (super_frame->bufs[i]->stream_type == CAM_STREAM_TYPE_RAW) {
   1350             mm_camera_buf_def_t * raw_frame = super_frame->bufs[i];
   1351             if (NULL != stream) {
   1352                 if (dump_raw) {
   1353                     pme->dumpFrameToFile(stream, raw_frame, QCAMERA_DUMP_FRM_RAW);
   1354                 }
   1355                 stream->bufDone(super_frame->bufs[i]->buf_idx);
   1356             }
   1357             break;
   1358         }
   1359     }
   1360 
   1361     free(super_frame);
   1362 
   1363     CDBG_HIGH("[KPI Perf] %s : END", __func__);
   1364 }
   1365 
   1366 /*===========================================================================
   1367  * FUNCTION   : snapshot_raw_stream_cb_routine
   1368  *
   1369  * DESCRIPTION: helper function to handle raw frame during standard capture
   1370  *
   1371  * PARAMETERS :
   1372  *   @super_frame : received super buffer
   1373  *   @stream      : stream object
   1374  *   @userdata    : user data ptr
   1375  *
   1376  * RETURN    : None
   1377  *
   1378  * NOTE      : caller passes the ownership of super_frame, it's our
   1379  *             responsibility to free super_frame once it's done.
   1380  *==========================================================================*/
   1381 void QCamera2HardwareInterface::snapshot_raw_stream_cb_routine(mm_camera_super_buf_t * super_frame,
   1382                                                                QCameraStream * stream,
   1383                                                                void * userdata)
   1384 {
   1385     ATRACE_CALL();
   1386     CDBG_HIGH("[KPI Perf] %s : BEGIN", __func__);
   1387     char value[PROPERTY_VALUE_MAX];
   1388     bool dump_raw = false;
   1389 
   1390     QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata;
   1391     if (pme == NULL ||
   1392         pme->mCameraHandle == NULL ||
   1393         pme->mCameraHandle->camera_handle != super_frame->camera_handle){
   1394         ALOGE("%s: camera obj not valid", __func__);
   1395         // simply free super frame
   1396         free(super_frame);
   1397         return;
   1398     }
   1399 
   1400     property_get("persist.camera.snapshot_raw", value, "0");
   1401     dump_raw = atoi(value) > 0 ? true : false;
   1402 
   1403     for (uint32_t i = 0; i < super_frame->num_bufs; i++) {
   1404         if (super_frame->bufs[i]->stream_type == CAM_STREAM_TYPE_RAW) {
   1405             mm_camera_buf_def_t * raw_frame = super_frame->bufs[i];
   1406             if (NULL != stream) {
   1407                 if (dump_raw) {
   1408                     pme->dumpFrameToFile(stream, raw_frame, QCAMERA_DUMP_FRM_RAW);
   1409                 }
   1410                 stream->bufDone(super_frame->bufs[i]->buf_idx);
   1411             }
   1412             break;
   1413         }
   1414     }
   1415 
   1416     free(super_frame);
   1417 
   1418     CDBG_HIGH("[KPI Perf] %s : END", __func__);
   1419 }
   1420 
   1421 /*===========================================================================
   1422  * FUNCTION   : updateMetadata
   1423  *
   1424  * DESCRIPTION: Frame related parameter can be updated here
   1425  *
   1426  * PARAMETERS :
   1427  *   @pMetaData : pointer to metadata buffer
   1428  *
   1429  * RETURN     : int32_t type of status
   1430  *              NO_ERROR  -- success
   1431  *              none-zero failure code
   1432  *==========================================================================*/
   1433 int32_t QCamera2HardwareInterface::updateMetadata(metadata_buffer_t *pMetaData)
   1434 {
   1435     int32_t rc = NO_ERROR;
   1436 
   1437     // Sharpness
   1438     cam_edge_application_t edge_application;
   1439     memset(&edge_application, 0x00, sizeof(cam_edge_application_t));
   1440     edge_application.sharpness = mParameters.getSharpness();
   1441     if (edge_application.sharpness != 0) {
   1442         edge_application.edge_mode = CAM_EDGE_MODE_FAST;
   1443     } else {
   1444         edge_application.edge_mode = CAM_EDGE_MODE_OFF;
   1445     }
   1446     ADD_SET_PARAM_ENTRY_TO_BATCH(pMetaData,
   1447             CAM_INTF_META_EDGE_MODE, edge_application);
   1448 
   1449     //Effect
   1450     int32_t prmEffect = mParameters.getEffect();
   1451     ADD_SET_PARAM_ENTRY_TO_BATCH(pMetaData, CAM_INTF_PARM_EFFECT, prmEffect);
   1452 
   1453     //flip
   1454     int32_t prmFlip = mParameters.getFlipMode(CAM_STREAM_TYPE_SNAPSHOT);
   1455     ADD_SET_PARAM_ENTRY_TO_BATCH(pMetaData, CAM_INTF_PARM_FLIP, prmFlip);
   1456 
   1457     //denoise
   1458     uint8_t prmDenoise = (uint8_t)mParameters.isWNREnabled();
   1459     ADD_SET_PARAM_ENTRY_TO_BATCH(pMetaData,
   1460             CAM_INTF_META_NOISE_REDUCTION_MODE, prmDenoise);
   1461 
   1462     //rotation & device rotation
   1463     uint32_t prmRotation = mParameters.getJpegRotation();
   1464     cam_rotation_info_t rotation_info;
   1465     if (prmRotation == 0) {
   1466        rotation_info.rotation = ROTATE_0;
   1467     } else if (prmRotation == 90) {
   1468        rotation_info.rotation = ROTATE_90;
   1469     } else if (prmRotation == 180) {
   1470        rotation_info.rotation = ROTATE_180;
   1471     } else if (prmRotation == 270) {
   1472        rotation_info.rotation = ROTATE_270;
   1473     }
   1474 
   1475     uint32_t device_rotation = mParameters.getDeviceRotation();
   1476     if (device_rotation == 0) {
   1477         rotation_info.device_rotation = ROTATE_0;
   1478     } else if (device_rotation == 90) {
   1479         rotation_info.device_rotation = ROTATE_90;
   1480     } else if (device_rotation == 180) {
   1481         rotation_info.device_rotation = ROTATE_180;
   1482     } else if (device_rotation == 270) {
   1483         rotation_info.device_rotation = ROTATE_270;
   1484     } else {
   1485         rotation_info.device_rotation = ROTATE_0;
   1486     }
   1487     ADD_SET_PARAM_ENTRY_TO_BATCH(pMetaData, CAM_INTF_PARM_ROTATION, rotation_info);
   1488 
   1489     return rc;
   1490 }
   1491 
   1492 /*===========================================================================
   1493  * FUNCTION   : metadata_stream_cb_routine
   1494  *
   1495  * DESCRIPTION: helper function to handle metadata frame from metadata stream
   1496  *
   1497  * PARAMETERS :
   1498  *   @super_frame : received super buffer
   1499  *   @stream      : stream object
   1500  *   @userdata    : user data ptr
   1501  *
   1502  * RETURN    : None
   1503  *
   1504  * NOTE      : caller passes the ownership of super_frame, it's our
   1505  *             responsibility to free super_frame once it's done. Metadata
   1506  *             could have valid entries for face detection result or
   1507  *             histogram statistics information.
   1508  *==========================================================================*/
   1509 void QCamera2HardwareInterface::metadata_stream_cb_routine(mm_camera_super_buf_t * super_frame,
   1510                                                            QCameraStream * stream,
   1511                                                            void * userdata)
   1512 {
   1513     ATRACE_CALL();
   1514     CDBG("[KPI Perf] %s : BEGIN", __func__);
   1515     QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata;
   1516     if (pme == NULL ||
   1517         pme->mCameraHandle == NULL ||
   1518         pme->mCameraHandle->camera_handle != super_frame->camera_handle){
   1519         ALOGE("%s: camera obj not valid", __func__);
   1520         // simply free super frame
   1521         free(super_frame);
   1522         return;
   1523     }
   1524 
   1525     mm_camera_buf_def_t *frame = super_frame->bufs[0];
   1526     metadata_buffer_t *pMetaData = (metadata_buffer_t *)frame->buffer;
   1527     if(pme->m_stateMachine.isNonZSLCaptureRunning()&&
   1528        !pme->mLongshotEnabled) {
   1529        //Make shutter call back in non ZSL mode once raw frame is received from VFE.
   1530        pme->playShutter();
   1531     }
   1532 
   1533     if (pMetaData->is_tuning_params_valid && pme->mParameters.getRecordingHintValue() == true) {
   1534         //Dump Tuning data for video
   1535         pme->dumpMetadataToFile(stream,frame,(char *)"Video");
   1536     }
   1537 
   1538     IF_META_AVAILABLE(cam_hist_stats_t, stats_data, CAM_INTF_META_HISTOGRAM, pMetaData) {
   1539         // process histogram statistics info
   1540         qcamera_sm_internal_evt_payload_t *payload =
   1541             (qcamera_sm_internal_evt_payload_t *)
   1542                 malloc(sizeof(qcamera_sm_internal_evt_payload_t));
   1543         if (NULL != payload) {
   1544             memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
   1545             payload->evt_type = QCAMERA_INTERNAL_EVT_HISTOGRAM_STATS;
   1546             payload->stats_data = *stats_data;
   1547             int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
   1548             if (rc != NO_ERROR) {
   1549                 ALOGE("%s: processEvt histogram failed", __func__);
   1550                 free(payload);
   1551                 payload = NULL;
   1552 
   1553             }
   1554         } else {
   1555             ALOGE("%s: No memory for histogram qcamera_sm_internal_evt_payload_t", __func__);
   1556         }
   1557     }
   1558 
   1559     IF_META_AVAILABLE(cam_face_detection_data_t, faces_data,
   1560             CAM_INTF_META_FACE_DETECTION, pMetaData) {
   1561         if (faces_data->num_faces_detected > MAX_ROI) {
   1562             ALOGE("%s: Invalid number of faces %d",
   1563                 __func__, faces_data->num_faces_detected);
   1564         } else {
   1565             // process face detection result
   1566             if (faces_data->num_faces_detected)
   1567                 CDBG_HIGH("[KPI Perf] %s: PROFILE_NUMBER_OF_FACES_DETECTED %d",
   1568                     __func__,faces_data->num_faces_detected);
   1569             faces_data->fd_type = QCAMERA_FD_PREVIEW; //HARD CODE here before MCT can support
   1570             qcamera_sm_internal_evt_payload_t *payload = (qcamera_sm_internal_evt_payload_t *)
   1571                 malloc(sizeof(qcamera_sm_internal_evt_payload_t));
   1572             if (NULL != payload) {
   1573                 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
   1574                 payload->evt_type = QCAMERA_INTERNAL_EVT_FACE_DETECT_RESULT;
   1575                 payload->faces_data = *faces_data;
   1576                 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
   1577                 if (rc != NO_ERROR) {
   1578                     ALOGE("%s: processEvt face detection failed", __func__);
   1579                     free(payload);
   1580                     payload = NULL;
   1581                 }
   1582             } else {
   1583                 ALOGE("%s: No memory for face detect qcamera_sm_internal_evt_payload_t", __func__);
   1584             }
   1585         }
   1586     }
   1587 
   1588     IF_META_AVAILABLE(cam_auto_focus_data_t, focus_data,
   1589             CAM_INTF_META_AUTOFOCUS_DATA, pMetaData) {
   1590         qcamera_sm_internal_evt_payload_t *payload =
   1591             (qcamera_sm_internal_evt_payload_t *)malloc(sizeof(qcamera_sm_internal_evt_payload_t));
   1592         if (NULL != payload) {
   1593             memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
   1594             payload->evt_type = QCAMERA_INTERNAL_EVT_FOCUS_UPDATE;
   1595             payload->focus_data = *focus_data;
   1596             payload->focus_data.focused_frame_idx = frame->frame_idx;
   1597             int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
   1598             if (rc != NO_ERROR) {
   1599                 ALOGE("%s: processEvt focus failed", __func__);
   1600                 free(payload);
   1601                 payload = NULL;
   1602 
   1603             }
   1604         } else {
   1605             ALOGE("%s: No memory for focus qcamera_sm_internal_evt_payload_t", __func__);
   1606         }
   1607     }
   1608 
   1609     IF_META_AVAILABLE(cam_crop_data_t, crop_data, CAM_INTF_META_CROP_DATA, pMetaData) {
   1610         if (crop_data->num_of_streams > MAX_NUM_STREAMS) {
   1611             ALOGE("%s: Invalid num_of_streams %d in crop_data", __func__,
   1612                 crop_data->num_of_streams);
   1613         } else {
   1614             qcamera_sm_internal_evt_payload_t *payload =
   1615                 (qcamera_sm_internal_evt_payload_t *)
   1616                     malloc(sizeof(qcamera_sm_internal_evt_payload_t));
   1617             if (NULL != payload) {
   1618                 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
   1619                 payload->evt_type = QCAMERA_INTERNAL_EVT_CROP_INFO;
   1620                 payload->crop_data = *crop_data;
   1621                 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
   1622                 if (rc != NO_ERROR) {
   1623                     ALOGE("%s: processEvt crop info failed", __func__);
   1624                     free(payload);
   1625                     payload = NULL;
   1626 
   1627                 }
   1628             } else {
   1629                 ALOGE("%s: No memory for prep_snapshot qcamera_sm_internal_evt_payload_t",
   1630                     __func__);
   1631             }
   1632         }
   1633     }
   1634 
   1635     IF_META_AVAILABLE(int32_t, prep_snapshot_done_state,
   1636             CAM_INTF_META_PREP_SNAPSHOT_DONE, pMetaData) {
   1637         qcamera_sm_internal_evt_payload_t *payload =
   1638         (qcamera_sm_internal_evt_payload_t *)malloc(sizeof(qcamera_sm_internal_evt_payload_t));
   1639         if (NULL != payload) {
   1640             memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
   1641             payload->evt_type = QCAMERA_INTERNAL_EVT_PREP_SNAPSHOT_DONE;
   1642             payload->prep_snapshot_state = (cam_prep_snapshot_state_t)*prep_snapshot_done_state;
   1643             int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
   1644             if (rc != NO_ERROR) {
   1645                 ALOGE("%s: processEvt prep_snapshot failed", __func__);
   1646                 free(payload);
   1647                 payload = NULL;
   1648 
   1649             }
   1650         } else {
   1651             ALOGE("%s: No memory for prep_snapshot qcamera_sm_internal_evt_payload_t", __func__);
   1652         }
   1653     }
   1654 
   1655     IF_META_AVAILABLE(cam_asd_hdr_scene_data_t, hdr_scene_data,
   1656             CAM_INTF_META_ASD_HDR_SCENE_DATA, pMetaData) {
   1657         CDBG_HIGH("%s: hdr_scene_data: %d %f\n", __func__,
   1658                 hdr_scene_data->is_hdr_scene, hdr_scene_data->hdr_confidence);
   1659         //Handle this HDR meta data only if capture is not in process
   1660         if (!pme->m_stateMachine.isCaptureRunning()) {
   1661             qcamera_sm_internal_evt_payload_t *payload =
   1662                     (qcamera_sm_internal_evt_payload_t *)
   1663                     malloc(sizeof(qcamera_sm_internal_evt_payload_t));
   1664             if (NULL != payload) {
   1665                 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
   1666                 payload->evt_type = QCAMERA_INTERNAL_EVT_HDR_UPDATE;
   1667                 payload->hdr_data = *hdr_scene_data;
   1668                 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
   1669                 if (rc != NO_ERROR) {
   1670                     ALOGE("%s: processEvt hdr update failed", __func__);
   1671                     free(payload);
   1672                     payload = NULL;
   1673                 }
   1674             } else {
   1675                 ALOGE("%s: No memory for hdr update qcamera_sm_internal_evt_payload_t",
   1676                         __func__);
   1677             }
   1678         }
   1679     }
   1680 
   1681     IF_META_AVAILABLE(int32_t, scene, CAM_INTF_META_ASD_SCENE_TYPE, pMetaData) {
   1682         qcamera_sm_internal_evt_payload_t *payload =
   1683             (qcamera_sm_internal_evt_payload_t *)malloc(sizeof(qcamera_sm_internal_evt_payload_t));
   1684         if (NULL != payload) {
   1685             memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
   1686             payload->evt_type = QCAMERA_INTERNAL_EVT_ASD_UPDATE;
   1687             payload->asd_data = (cam_auto_scene_t)*scene;
   1688             int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
   1689             if (rc != NO_ERROR) {
   1690                 ALOGE("%s: processEvt asd_update failed", __func__);
   1691                 free(payload);
   1692                 payload = NULL;
   1693             }
   1694         } else {
   1695             ALOGE("%s: No memory for asd_update qcamera_sm_internal_evt_payload_t", __func__);
   1696         }
   1697     }
   1698 
   1699     IF_META_AVAILABLE(cam_awb_params_t, awb_params, CAM_INTF_META_AWB_INFO, pMetaData) {
   1700         CDBG_HIGH("%s, metadata for awb params.", __func__);
   1701         qcamera_sm_internal_evt_payload_t *payload =
   1702                 (qcamera_sm_internal_evt_payload_t *)
   1703                 malloc(sizeof(qcamera_sm_internal_evt_payload_t));
   1704         if (NULL != payload) {
   1705             memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
   1706             payload->evt_type = QCAMERA_INTERNAL_EVT_AWB_UPDATE;
   1707             payload->awb_data = *awb_params;
   1708             int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
   1709             if (rc != NO_ERROR) {
   1710                 ALOGE("%s: processEvt awb_update failed", __func__);
   1711                 free(payload);
   1712                 payload = NULL;
   1713             }
   1714         } else {
   1715             ALOGE("%s: No memory for awb_update qcamera_sm_internal_evt_payload_t", __func__);
   1716         }
   1717     }
   1718 
   1719     IF_META_AVAILABLE(uint32_t, flash_mode, CAM_INTF_META_FLASH_MODE, pMetaData) {
   1720         pme->mExifParams.sensor_params.flash_mode = (cam_flash_mode_t)*flash_mode;
   1721     }
   1722 
   1723     IF_META_AVAILABLE(int32_t, flash_state, CAM_INTF_META_FLASH_STATE, pMetaData) {
   1724         pme->mExifParams.sensor_params.flash_state = (cam_flash_state_t) *flash_state;
   1725     }
   1726 
   1727     IF_META_AVAILABLE(float, aperture_value, CAM_INTF_META_LENS_APERTURE, pMetaData) {
   1728         pme->mExifParams.sensor_params.aperture_value = *aperture_value;
   1729     }
   1730 
   1731     IF_META_AVAILABLE(cam_3a_params_t, ae_params, CAM_INTF_META_AEC_INFO, pMetaData) {
   1732         pme->mExifParams.cam_3a_params = *ae_params;
   1733         pme->mExifParams.cam_3a_params_valid = TRUE;
   1734         pme->mFlashNeeded = ae_params->flash_needed;
   1735         pme->mExifParams.cam_3a_params.brightness = (float) pme->mParameters.getBrightness();
   1736         qcamera_sm_internal_evt_payload_t *payload =
   1737                 (qcamera_sm_internal_evt_payload_t *)
   1738                 malloc(sizeof(qcamera_sm_internal_evt_payload_t));
   1739         if (NULL != payload) {
   1740             memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
   1741             payload->evt_type = QCAMERA_INTERNAL_EVT_AE_UPDATE;
   1742             payload->ae_data = *ae_params;
   1743             int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
   1744             if (rc != NO_ERROR) {
   1745                 ALOGE("%s: processEvt ae_update failed", __func__);
   1746                 free(payload);
   1747                 payload = NULL;
   1748             }
   1749         } else {
   1750             ALOGE("%s: No memory for ae_update qcamera_sm_internal_evt_payload_t", __func__);
   1751         }
   1752     }
   1753 
   1754     IF_META_AVAILABLE(int32_t, wb_mode, CAM_INTF_PARM_WHITE_BALANCE, pMetaData) {
   1755         pme->mExifParams.cam_3a_params.wb_mode = (cam_wb_mode_type) *wb_mode;
   1756     }
   1757 
   1758     IF_META_AVAILABLE(cam_sensor_params_t, sensor_params, CAM_INTF_META_SENSOR_INFO, pMetaData) {
   1759         pme->mExifParams.sensor_params = *sensor_params;
   1760     }
   1761 
   1762     IF_META_AVAILABLE(cam_ae_exif_debug_t, ae_exif_debug_params,
   1763             CAM_INTF_META_EXIF_DEBUG_AE, pMetaData) {
   1764         pme->mExifParams.ae_debug_params = *ae_exif_debug_params;
   1765         pme->mExifParams.ae_debug_params_valid = TRUE;
   1766     }
   1767 
   1768     IF_META_AVAILABLE(cam_awb_exif_debug_t, awb_exif_debug_params,
   1769             CAM_INTF_META_EXIF_DEBUG_AWB, pMetaData) {
   1770         pme->mExifParams.awb_debug_params = *awb_exif_debug_params;
   1771         pme->mExifParams.awb_debug_params_valid = TRUE;
   1772     }
   1773 
   1774     IF_META_AVAILABLE(cam_af_exif_debug_t, af_exif_debug_params,
   1775             CAM_INTF_META_EXIF_DEBUG_AF, pMetaData) {
   1776         pme->mExifParams.af_debug_params = *af_exif_debug_params;
   1777         pme->mExifParams.af_debug_params_valid = TRUE;
   1778     }
   1779 
   1780     IF_META_AVAILABLE(cam_asd_exif_debug_t, asd_exif_debug_params,
   1781             CAM_INTF_META_EXIF_DEBUG_ASD, pMetaData) {
   1782         pme->mExifParams.asd_debug_params = *asd_exif_debug_params;
   1783         pme->mExifParams.asd_debug_params_valid = TRUE;
   1784     }
   1785 
   1786     IF_META_AVAILABLE(cam_stats_buffer_exif_debug_t, stats_exif_debug_params,
   1787             CAM_INTF_META_EXIF_DEBUG_STATS, pMetaData) {
   1788         pme->mExifParams.stats_debug_params = *stats_exif_debug_params;
   1789         pme->mExifParams.stats_debug_params_valid = TRUE;
   1790     }
   1791 
   1792     IF_META_AVAILABLE(uint32_t, led_mode, CAM_INTF_META_LED_MODE_OVERRIDE, pMetaData) {
   1793         qcamera_sm_internal_evt_payload_t *payload =
   1794                 (qcamera_sm_internal_evt_payload_t *)
   1795                 malloc(sizeof(qcamera_sm_internal_evt_payload_t));
   1796         if (NULL != payload) {
   1797             memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
   1798             payload->evt_type = QCAMERA_INTERNAL_EVT_LED_MODE_OVERRIDE;
   1799             payload->led_data = (cam_flash_mode_t)*led_mode;
   1800             int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
   1801             if (rc != NO_ERROR) {
   1802                 ALOGE("%s: processEvt led mode override failed", __func__);
   1803                 free(payload);
   1804                 payload = NULL;
   1805             }
   1806         } else {
   1807             ALOGE("%s: No memory for focus qcamera_sm_internal_evt_payload_t", __func__);
   1808         }
   1809     }
   1810 
   1811     cam_edge_application_t edge_application;
   1812     memset(&edge_application, 0x00, sizeof(cam_edge_application_t));
   1813     edge_application.sharpness = pme->mParameters.getSharpness();
   1814     if (edge_application.sharpness != 0) {
   1815         edge_application.edge_mode = CAM_EDGE_MODE_FAST;
   1816     } else {
   1817         edge_application.edge_mode = CAM_EDGE_MODE_OFF;
   1818     }
   1819     ADD_SET_PARAM_ENTRY_TO_BATCH(pMetaData, CAM_INTF_META_EDGE_MODE, edge_application);
   1820 
   1821     IF_META_AVAILABLE(cam_focus_pos_info_t, cur_pos_info,
   1822             CAM_INTF_META_FOCUS_POSITION, pMetaData) {
   1823         qcamera_sm_internal_evt_payload_t *payload =
   1824             (qcamera_sm_internal_evt_payload_t *)malloc(sizeof(qcamera_sm_internal_evt_payload_t));
   1825         if (NULL != payload) {
   1826             memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
   1827             payload->evt_type = QCAMERA_INTERNAL_EVT_FOCUS_POS_UPDATE;
   1828             payload->focus_pos = *cur_pos_info;
   1829             int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
   1830             if (rc != NO_ERROR) {
   1831                 ALOGE("%s: processEvt focus_pos_update failed", __func__);
   1832                 free(payload);
   1833                 payload = NULL;
   1834             }
   1835         } else {
   1836             ALOGE("%s: No memory for focus_pos_update qcamera_sm_internal_evt_payload_t", __func__);
   1837         }
   1838     }
   1839 
   1840     //Function to upadte metadata for frame based parameter
   1841     pme->updateMetadata(pMetaData);
   1842 
   1843     stream->bufDone(frame->buf_idx);
   1844     free(super_frame);
   1845 
   1846     CDBG("[KPI Perf] %s : END", __func__);
   1847 }
   1848 
   1849 /*===========================================================================
   1850  * FUNCTION   : reprocess_stream_cb_routine
   1851  *
   1852  * DESCRIPTION: helper function to handle reprocess frame from reprocess stream
   1853                 (after reprocess, e.g., ZSL snapshot frame after WNR if
   1854  *              WNR is enabled)
   1855  *
   1856  * PARAMETERS :
   1857  *   @super_frame : received super buffer
   1858  *   @stream      : stream object
   1859  *   @userdata    : user data ptr
   1860  *
   1861  * RETURN    : None
   1862  *
   1863  * NOTE      : caller passes the ownership of super_frame, it's our
   1864  *             responsibility to free super_frame once it's done. In this
   1865  *             case, reprocessed frame need to be passed to postprocessor
   1866  *             for jpeg encoding.
   1867  *==========================================================================*/
   1868 void QCamera2HardwareInterface::reprocess_stream_cb_routine(mm_camera_super_buf_t * super_frame,
   1869                                                             QCameraStream * /*stream*/,
   1870                                                             void * userdata)
   1871 {
   1872     ATRACE_CALL();
   1873     CDBG_HIGH("[KPI Perf] %s: E", __func__);
   1874     QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata;
   1875     if (pme == NULL ||
   1876         pme->mCameraHandle == NULL ||
   1877         pme->mCameraHandle->camera_handle != super_frame->camera_handle){
   1878         ALOGE("%s: camera obj not valid", __func__);
   1879         // simply free super frame
   1880         free(super_frame);
   1881         return;
   1882     }
   1883 
   1884     pme->m_postprocessor.processPPData(super_frame);
   1885 
   1886     CDBG_HIGH("[KPI Perf] %s: X", __func__);
   1887 }
   1888 
   1889 /*===========================================================================
   1890  * FUNCTION   : dumpFrameToFile
   1891  *
   1892  * DESCRIPTION: helper function to dump jpeg into file for debug purpose.
   1893  *
   1894  * PARAMETERS :
   1895  *    @data : data ptr
   1896  *    @size : length of data buffer
   1897  *    @index : identifier for data
   1898  *
   1899  * RETURN     : None
   1900  *==========================================================================*/
   1901 void QCamera2HardwareInterface::dumpJpegToFile(const void *data,
   1902         size_t size, uint32_t index)
   1903 {
   1904     char value[PROPERTY_VALUE_MAX];
   1905     property_get("persist.camera.dumpimg", value, "0");
   1906     uint32_t enabled = (uint32_t) atoi(value);
   1907     uint32_t frm_num = 0;
   1908     uint32_t skip_mode = 0;
   1909 
   1910     char buf[32];
   1911     cam_dimension_t dim;
   1912     memset(buf, 0, sizeof(buf));
   1913     memset(&dim, 0, sizeof(dim));
   1914 
   1915     if(((enabled & QCAMERA_DUMP_FRM_JPEG) && data) ||
   1916         ((true == m_bIntJpegEvtPending) && data)) {
   1917         frm_num = ((enabled & 0xffff0000) >> 16);
   1918         if(frm_num == 0) {
   1919             frm_num = 10; //default 10 frames
   1920         }
   1921         if(frm_num > 256) {
   1922             frm_num = 256; //256 buffers cycle around
   1923         }
   1924         skip_mode = ((enabled & 0x0000ff00) >> 8);
   1925         if(skip_mode == 0) {
   1926             skip_mode = 1; //no-skip
   1927         }
   1928 
   1929         if( mDumpSkipCnt % skip_mode == 0) {
   1930             if((frm_num == 256) && (mDumpFrmCnt >= frm_num)) {
   1931                 // reset frame count if cycling
   1932                 mDumpFrmCnt = 0;
   1933             }
   1934             if (mDumpFrmCnt <= frm_num) {
   1935                 snprintf(buf, sizeof(buf), QCAMERA_DUMP_FRM_LOCATION "%d_%d.jpg",
   1936                         mDumpFrmCnt, index);
   1937                 if (true == m_bIntJpegEvtPending) {
   1938                     strlcpy(m_BackendFileName, buf, sizeof(buf));
   1939                     mBackendFileSize = size;
   1940                 }
   1941 
   1942                 int file_fd = open(buf, O_RDWR | O_CREAT, 0777);
   1943                 if (file_fd > 0) {
   1944                     ssize_t written_len = write(file_fd, data, size);
   1945                     fchmod(file_fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
   1946                     CDBG_HIGH("%s: written number of bytes %zd\n",
   1947                             __func__, written_len);
   1948                     close(file_fd);
   1949                 } else {
   1950                     ALOGE("%s: fail t open file for image dumping", __func__);
   1951                 }
   1952                 if (false == m_bIntJpegEvtPending) {
   1953                     mDumpFrmCnt++;
   1954                 }
   1955             }
   1956         }
   1957         mDumpSkipCnt++;
   1958     }
   1959 }
   1960 
   1961 
   1962 void QCamera2HardwareInterface::dumpMetadataToFile(QCameraStream *stream,
   1963                                                    mm_camera_buf_def_t *frame,char *type)
   1964 {
   1965     char value[PROPERTY_VALUE_MAX];
   1966     uint32_t frm_num = 0;
   1967     metadata_buffer_t *metadata = (metadata_buffer_t *)frame->buffer;
   1968     property_get("persist.camera.dumpmetadata", value, "0");
   1969     uint32_t enabled = (uint32_t) atoi(value);
   1970     if (stream == NULL) {
   1971         CDBG_HIGH("No op");
   1972         return;
   1973     }
   1974 
   1975     uint32_t dumpFrmCnt = stream->mDumpMetaFrame;
   1976     if(enabled){
   1977         frm_num = ((enabled & 0xffff0000) >> 16);
   1978         if (frm_num == 0) {
   1979             frm_num = 10; //default 10 frames
   1980         }
   1981         if (frm_num > 256) {
   1982             frm_num = 256; //256 buffers cycle around
   1983         }
   1984         if ((frm_num == 256) && (dumpFrmCnt >= frm_num)) {
   1985             // reset frame count if cycling
   1986             dumpFrmCnt = 0;
   1987         }
   1988         CDBG_HIGH("dumpFrmCnt= %u, frm_num = %u", dumpFrmCnt, frm_num);
   1989         if (dumpFrmCnt < frm_num) {
   1990             char timeBuf[128];
   1991             char buf[32];
   1992             memset(buf, 0, sizeof(buf));
   1993             memset(timeBuf, 0, sizeof(timeBuf));
   1994             time_t current_time;
   1995             struct tm * timeinfo;
   1996             time (&current_time);
   1997             timeinfo = localtime (&current_time);
   1998             if (NULL != timeinfo) {
   1999                 strftime(timeBuf, sizeof(timeBuf),
   2000                         QCAMERA_DUMP_FRM_LOCATION "%Y%m%d%H%M%S", timeinfo);
   2001             }
   2002             String8 filePath(timeBuf);
   2003             snprintf(buf, sizeof(buf), "%um_%s_%d.bin", dumpFrmCnt, type, frame->frame_idx);
   2004             filePath.append(buf);
   2005             int file_fd = open(filePath.string(), O_RDWR | O_CREAT, 0777);
   2006             if (file_fd > 0) {
   2007                 ssize_t written_len = 0;
   2008                 metadata->tuning_params.tuning_data_version = TUNING_DATA_VERSION;
   2009                 void *data = (void *)((uint8_t *)&metadata->tuning_params.tuning_data_version);
   2010                 written_len += write(file_fd, data, sizeof(uint32_t));
   2011                 data = (void *)((uint8_t *)&metadata->tuning_params.tuning_sensor_data_size);
   2012                 CDBG_HIGH("tuning_sensor_data_size %d",(int)(*(int *)data));
   2013                 written_len += write(file_fd, data, sizeof(uint32_t));
   2014                 data = (void *)((uint8_t *)&metadata->tuning_params.tuning_vfe_data_size);
   2015                 CDBG_HIGH("tuning_vfe_data_size %d",(int)(*(int *)data));
   2016                 written_len += write(file_fd, data, sizeof(uint32_t));
   2017                 data = (void *)((uint8_t *)&metadata->tuning_params.tuning_cpp_data_size);
   2018                 CDBG_HIGH("tuning_cpp_data_size %d",(int)(*(int *)data));
   2019                 written_len += write(file_fd, data, sizeof(uint32_t));
   2020                 data = (void *)((uint8_t *)&metadata->tuning_params.tuning_cac_data_size);
   2021                 CDBG_HIGH("tuning_cac_data_size %d",(int)(*(int *)data));
   2022                 written_len += write(file_fd, data, sizeof(uint32_t));
   2023                 data = (void *)((uint8_t *)&metadata->tuning_params.tuning_cac_data_size2);
   2024                 CDBG_HIGH("%s < skrajago >tuning_cac_data_size %d",__func__,(int)(*(int *)data));
   2025                 written_len += write(file_fd, data, sizeof(uint32_t));
   2026                 size_t total_size = metadata->tuning_params.tuning_sensor_data_size;
   2027                 data = (void *)((uint8_t *)&metadata->tuning_params.data);
   2028                 written_len += write(file_fd, data, total_size);
   2029                 total_size = metadata->tuning_params.tuning_vfe_data_size;
   2030                 data = (void *)((uint8_t *)&metadata->tuning_params.data[TUNING_VFE_DATA_OFFSET]);
   2031                 written_len += write(file_fd, data, total_size);
   2032                 total_size = metadata->tuning_params.tuning_cpp_data_size;
   2033                 data = (void *)((uint8_t *)&metadata->tuning_params.data[TUNING_CPP_DATA_OFFSET]);
   2034                 written_len += write(file_fd, data, total_size);
   2035                 total_size = metadata->tuning_params.tuning_cac_data_size;
   2036                 data = (void *)((uint8_t *)&metadata->tuning_params.data[TUNING_CAC_DATA_OFFSET]);
   2037                 written_len += write(file_fd, data, total_size);
   2038                 close(file_fd);
   2039             }else {
   2040                 ALOGE("%s: fail t open file for image dumping", __func__);
   2041             }
   2042             dumpFrmCnt++;
   2043         }
   2044     }
   2045     stream->mDumpMetaFrame = dumpFrmCnt;
   2046 }
   2047 /*===========================================================================
   2048  * FUNCTION   : dumpFrameToFile
   2049  *
   2050  * DESCRIPTION: helper function to dump frame into file for debug purpose.
   2051  *
   2052  * PARAMETERS :
   2053  *    @data : data ptr
   2054  *    @size : length of data buffer
   2055  *    @index : identifier for data
   2056  *    @dump_type : type of the frame to be dumped. Only such
   2057  *                 dump type is enabled, the frame will be
   2058  *                 dumped into a file.
   2059  *
   2060  * RETURN     : None
   2061  *==========================================================================*/
   2062 void QCamera2HardwareInterface::dumpFrameToFile(QCameraStream *stream,
   2063         mm_camera_buf_def_t *frame, uint32_t dump_type)
   2064 {
   2065     char value[PROPERTY_VALUE_MAX];
   2066     property_get("persist.camera.dumpimg", value, "0");
   2067     uint32_t enabled = (uint32_t) atoi(value);
   2068     uint32_t frm_num = 0;
   2069     uint32_t skip_mode = 0;
   2070 
   2071     if (NULL == stream) {
   2072         ALOGE("%s stream object is null", __func__);
   2073         return;
   2074     }
   2075 
   2076     uint32_t dumpFrmCnt = stream->mDumpFrame;
   2077 
   2078     if (true == m_bIntRawEvtPending) {
   2079         enabled = QCAMERA_DUMP_FRM_RAW;
   2080     }
   2081 
   2082     if((enabled & QCAMERA_DUMP_FRM_MASK_ALL)) {
   2083         if((enabled & dump_type) && stream && frame) {
   2084             frm_num = ((enabled & 0xffff0000) >> 16);
   2085             if(frm_num == 0) {
   2086                 frm_num = 10; //default 10 frames
   2087             }
   2088             if(frm_num > 256) {
   2089                 frm_num = 256; //256 buffers cycle around
   2090             }
   2091             skip_mode = ((enabled & 0x0000ff00) >> 8);
   2092             if(skip_mode == 0) {
   2093                 skip_mode = 1; //no-skip
   2094             }
   2095             if(stream->mDumpSkipCnt == 0)
   2096                 stream->mDumpSkipCnt = 1;
   2097 
   2098             if( stream->mDumpSkipCnt % skip_mode == 0) {
   2099                 if((frm_num == 256) && (dumpFrmCnt >= frm_num)) {
   2100                     // reset frame count if cycling
   2101                     dumpFrmCnt = 0;
   2102                 }
   2103                 if (dumpFrmCnt <= frm_num) {
   2104                     char buf[32];
   2105                     char timeBuf[128];
   2106                     time_t current_time;
   2107                     struct tm * timeinfo;
   2108 
   2109                     memset(timeBuf, 0, sizeof(timeBuf));
   2110 
   2111                     time (&current_time);
   2112                     timeinfo = localtime (&current_time);
   2113                     memset(buf, 0, sizeof(buf));
   2114 
   2115                     cam_dimension_t dim;
   2116                     memset(&dim, 0, sizeof(dim));
   2117                     stream->getFrameDimension(dim);
   2118 
   2119                     cam_frame_len_offset_t offset;
   2120                     memset(&offset, 0, sizeof(cam_frame_len_offset_t));
   2121                     stream->getFrameOffset(offset);
   2122 
   2123                     if (NULL != timeinfo) {
   2124                         strftime(timeBuf, sizeof(timeBuf),
   2125                                 QCAMERA_DUMP_FRM_LOCATION "%Y%m%d%H%M%S", timeinfo);
   2126                     }
   2127                     String8 filePath(timeBuf);
   2128                     switch (dump_type) {
   2129                     case QCAMERA_DUMP_FRM_PREVIEW:
   2130                         {
   2131                             snprintf(buf, sizeof(buf), "%dp_%dx%d_%d.yuv",
   2132                                     dumpFrmCnt, dim.width, dim.height, frame->frame_idx);
   2133                         }
   2134                         break;
   2135                     case QCAMERA_DUMP_FRM_THUMBNAIL:
   2136                         {
   2137                             snprintf(buf, sizeof(buf), "%dt_%dx%d_%d.yuv",
   2138                                     dumpFrmCnt, dim.width, dim.height, frame->frame_idx);
   2139                         }
   2140                         break;
   2141                     case QCAMERA_DUMP_FRM_SNAPSHOT:
   2142                         {
   2143                             mParameters.getStreamDimension(CAM_STREAM_TYPE_SNAPSHOT, dim);
   2144                             snprintf(buf, sizeof(buf), "%ds_%dx%d_%d.yuv",
   2145                                     dumpFrmCnt, dim.width, dim.height, frame->frame_idx);
   2146                         }
   2147                         break;
   2148                     case QCAMERA_DUMP_FRM_VIDEO:
   2149                         {
   2150                             snprintf(buf, sizeof(buf), "%dv_%dx%d_%d.yuv",
   2151                                     dumpFrmCnt, dim.width, dim.height, frame->frame_idx);
   2152                         }
   2153                         break;
   2154                     case QCAMERA_DUMP_FRM_RAW:
   2155                         {
   2156                             mParameters.getStreamDimension(CAM_STREAM_TYPE_RAW, dim);
   2157                             snprintf(buf, sizeof(buf), "%dr_%dx%d_%d.raw",
   2158                                     dumpFrmCnt, dim.width, dim.height, frame->frame_idx);
   2159                         }
   2160                         break;
   2161                     case QCAMERA_DUMP_FRM_JPEG:
   2162                         {
   2163                             mParameters.getStreamDimension(CAM_STREAM_TYPE_SNAPSHOT, dim);
   2164                             snprintf(buf, sizeof(buf), "%dj_%dx%d_%d.yuv",
   2165                                     dumpFrmCnt, dim.width, dim.height, frame->frame_idx);
   2166                         }
   2167                         break;
   2168                     default:
   2169                         ALOGE("%s: Not supported for dumping stream type %d",
   2170                               __func__, dump_type);
   2171                         return;
   2172                     }
   2173 
   2174                     filePath.append(buf);
   2175                     int file_fd = open(filePath.string(), O_RDWR | O_CREAT, 0777);
   2176                     ssize_t written_len = 0;
   2177                     if (file_fd > 0) {
   2178                         void *data = NULL;
   2179 
   2180                         fchmod(file_fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
   2181                         for (uint32_t i = 0; i < offset.num_planes; i++) {
   2182                             uint32_t index = offset.mp[i].offset;
   2183                             if (i > 0) {
   2184                                 index += offset.mp[i-1].len;
   2185                             }
   2186                             for (int j = 0; j < offset.mp[i].height; j++) {
   2187                                 data = (void *)((uint8_t *)frame->buffer + index);
   2188                                 written_len += write(file_fd, data,
   2189                                         (size_t)offset.mp[i].width);
   2190                                 index += (uint32_t)offset.mp[i].stride;
   2191                             }
   2192                         }
   2193 
   2194                         CDBG_HIGH("%s: written number of bytes %ld\n",
   2195                             __func__, written_len);
   2196                         close(file_fd);
   2197                     } else {
   2198                         ALOGE("%s: fail t open file for image dumping", __func__);
   2199                     }
   2200                     if (true == m_bIntRawEvtPending) {
   2201                         strlcpy(m_BackendFileName, filePath.string(), QCAMERA_MAX_FILEPATH_LENGTH);
   2202                         mBackendFileSize = (size_t)written_len;
   2203                     } else {
   2204                         dumpFrmCnt++;
   2205                     }
   2206                 }
   2207             }
   2208             stream->mDumpSkipCnt++;
   2209         }
   2210     } else {
   2211         dumpFrmCnt = 0;
   2212     }
   2213     stream->mDumpFrame = dumpFrmCnt;
   2214 }
   2215 
   2216 /*===========================================================================
   2217  * FUNCTION   : debugShowVideoFPS
   2218  *
   2219  * DESCRIPTION: helper function to log video frame FPS for debug purpose.
   2220  *
   2221  * PARAMETERS : None
   2222  *
   2223  * RETURN     : None
   2224  *==========================================================================*/
   2225 void QCamera2HardwareInterface::debugShowVideoFPS()
   2226 {
   2227     mVFrameCount++;
   2228     nsecs_t now = systemTime();
   2229     nsecs_t diff = now - mVLastFpsTime;
   2230     if (diff > ms2ns(250)) {
   2231         mVFps = (((double)(mVFrameCount - mVLastFrameCount)) *
   2232                 (double)(s2ns(1))) / (double)diff;
   2233         CDBG_HIGH("Video Frames Per Second: %.4f Cam ID = %d", mVFps, mCameraId);
   2234         mVLastFpsTime = now;
   2235         mVLastFrameCount = mVFrameCount;
   2236     }
   2237 }
   2238 
   2239 /*===========================================================================
   2240  * FUNCTION   : debugShowPreviewFPS
   2241  *
   2242  * DESCRIPTION: helper function to log preview frame FPS for debug purpose.
   2243  *
   2244  * PARAMETERS : None
   2245  *
   2246  * RETURN     : None
   2247  *==========================================================================*/
   2248 void QCamera2HardwareInterface::debugShowPreviewFPS()
   2249 {
   2250     mPFrameCount++;
   2251     nsecs_t now = systemTime();
   2252     nsecs_t diff = now - mPLastFpsTime;
   2253     if (diff > ms2ns(250)) {
   2254         mPFps = (((double)(mPFrameCount - mPLastFrameCount)) *
   2255                 (double)(s2ns(1))) / (double)diff;
   2256         CDBG_HIGH("[KPI Perf] %s: PROFILE_PREVIEW_FRAMES_PER_SECOND : %.4f Cam ID = %d",
   2257                 __func__, mPFps, mCameraId);
   2258         mPLastFpsTime = now;
   2259         mPLastFrameCount = mPFrameCount;
   2260     }
   2261 }
   2262 
   2263 /*===========================================================================
   2264  * FUNCTION   : ~QCameraCbNotifier
   2265  *
   2266  * DESCRIPTION: Destructor for exiting the callback context.
   2267  *
   2268  * PARAMETERS : None
   2269  *
   2270  * RETURN     : None
   2271  *==========================================================================*/
   2272 QCameraCbNotifier::~QCameraCbNotifier()
   2273 {
   2274 }
   2275 
   2276 /*===========================================================================
   2277  * FUNCTION   : exit
   2278  *
   2279  * DESCRIPTION: exit notify thread.
   2280  *
   2281  * PARAMETERS : None
   2282  *
   2283  * RETURN     : None
   2284  *==========================================================================*/
   2285 void QCameraCbNotifier::exit()
   2286 {
   2287     mActive = false;
   2288     mProcTh.exit();
   2289 }
   2290 
   2291 /*===========================================================================
   2292  * FUNCTION   : releaseNotifications
   2293  *
   2294  * DESCRIPTION: callback for releasing data stored in the callback queue.
   2295  *
   2296  * PARAMETERS :
   2297  *   @data      : data to be released
   2298  *   @user_data : context data
   2299  *
   2300  * RETURN     : None
   2301  *==========================================================================*/
   2302 void QCameraCbNotifier::releaseNotifications(void *data, void *user_data)
   2303 {
   2304     qcamera_callback_argm_t *arg = ( qcamera_callback_argm_t * ) data;
   2305 
   2306     if ( ( NULL != arg ) && ( NULL != user_data ) ) {
   2307         if ( arg->release_cb ) {
   2308             arg->release_cb(arg->user_data, arg->cookie, FAILED_TRANSACTION);
   2309         }
   2310     }
   2311 }
   2312 
   2313 /*===========================================================================
   2314  * FUNCTION   : matchSnapshotNotifications
   2315  *
   2316  * DESCRIPTION: matches snapshot data callbacks
   2317  *
   2318  * PARAMETERS :
   2319  *   @data      : data to match
   2320  *   @user_data : context data
   2321  *
   2322  * RETURN     : bool match
   2323  *              true - match found
   2324  *              false- match not found
   2325  *==========================================================================*/
   2326 bool QCameraCbNotifier::matchSnapshotNotifications(void *data,
   2327                                                    void */*user_data*/)
   2328 {
   2329     qcamera_callback_argm_t *arg = ( qcamera_callback_argm_t * ) data;
   2330     if ( NULL != arg ) {
   2331         if ( QCAMERA_DATA_SNAPSHOT_CALLBACK == arg->cb_type ) {
   2332             return true;
   2333         }
   2334     }
   2335 
   2336     return false;
   2337 }
   2338 
   2339 /*===========================================================================
   2340  * FUNCTION   : matchPreviewNotifications
   2341  *
   2342  * DESCRIPTION: matches preview data callbacks
   2343  *
   2344  * PARAMETERS :
   2345  *   @data      : data to match
   2346  *   @user_data : context data
   2347  *
   2348  * RETURN     : bool match
   2349  *              true - match found
   2350  *              false- match not found
   2351  *==========================================================================*/
   2352 bool QCameraCbNotifier::matchPreviewNotifications(void *data,
   2353         void */*user_data*/)
   2354 {
   2355     qcamera_callback_argm_t *arg = ( qcamera_callback_argm_t * ) data;
   2356     if (NULL != arg) {
   2357         if ((QCAMERA_DATA_CALLBACK == arg->cb_type) &&
   2358                 (CAMERA_MSG_PREVIEW_FRAME == arg->msg_type)) {
   2359             return true;
   2360         }
   2361     }
   2362 
   2363     return false;
   2364 }
   2365 
   2366 /*===========================================================================
   2367  * FUNCTION   : cbNotifyRoutine
   2368  *
   2369  * DESCRIPTION: callback thread which interfaces with the upper layers
   2370  *              given input commands.
   2371  *
   2372  * PARAMETERS :
   2373  *   @data    : context data
   2374  *
   2375  * RETURN     : None
   2376  *==========================================================================*/
   2377 void * QCameraCbNotifier::cbNotifyRoutine(void * data)
   2378 {
   2379     int running = 1;
   2380     int ret;
   2381     QCameraCbNotifier *pme = (QCameraCbNotifier *)data;
   2382     QCameraCmdThread *cmdThread = &pme->mProcTh;
   2383     cmdThread->setName("CAM_cbNotify");
   2384     uint8_t isSnapshotActive = FALSE;
   2385     bool longShotEnabled = false;
   2386     uint32_t numOfSnapshotExpected = 0;
   2387     uint32_t numOfSnapshotRcvd = 0;
   2388     int32_t cbStatus = NO_ERROR;
   2389 
   2390     CDBG("%s: E", __func__);
   2391     do {
   2392         do {
   2393             ret = cam_sem_wait(&cmdThread->cmd_sem);
   2394             if (ret != 0 && errno != EINVAL) {
   2395                 CDBG("%s: cam_sem_wait error (%s)",
   2396                            __func__, strerror(errno));
   2397                 return NULL;
   2398             }
   2399         } while (ret != 0);
   2400 
   2401         camera_cmd_type_t cmd = cmdThread->getCmd();
   2402         CDBG("%s: get cmd %d", __func__, cmd);
   2403         switch (cmd) {
   2404         case CAMERA_CMD_TYPE_START_DATA_PROC:
   2405             {
   2406                 isSnapshotActive = TRUE;
   2407                 numOfSnapshotExpected = pme->mParent->numOfSnapshotsExpected();
   2408                 longShotEnabled = pme->mParent->isLongshotEnabled();
   2409                 ALOGI("%s: Num Snapshots Expected = %d",
   2410                   __func__, numOfSnapshotExpected);
   2411                 numOfSnapshotRcvd = 0;
   2412             }
   2413             break;
   2414         case CAMERA_CMD_TYPE_STOP_DATA_PROC:
   2415             {
   2416                 pme->mDataQ.flushNodes(matchSnapshotNotifications);
   2417                 isSnapshotActive = FALSE;
   2418 
   2419                 numOfSnapshotExpected = 0;
   2420                 numOfSnapshotRcvd = 0;
   2421             }
   2422             break;
   2423         case CAMERA_CMD_TYPE_DO_NEXT_JOB:
   2424             {
   2425                 qcamera_callback_argm_t *cb =
   2426                     (qcamera_callback_argm_t *)pme->mDataQ.dequeue();
   2427                 cbStatus = NO_ERROR;
   2428                 if (NULL != cb) {
   2429                     CDBG("%s: cb type %d received",
   2430                           __func__,
   2431                           cb->cb_type);
   2432 
   2433                     if (pme->mParent->msgTypeEnabledWithLock(cb->msg_type)) {
   2434                         switch (cb->cb_type) {
   2435                         case QCAMERA_NOTIFY_CALLBACK:
   2436                             {
   2437                                 if (cb->msg_type == CAMERA_MSG_FOCUS) {
   2438                                     ATRACE_INT("Camera:AutoFocus", 0);
   2439                                     CDBG_HIGH("[KPI Perf] %s : PROFILE_SENDING_FOCUS_EVT_TO APP",
   2440                                         __func__);
   2441                                 }
   2442                                 if (pme->mNotifyCb) {
   2443                                     pme->mNotifyCb(cb->msg_type,
   2444                                                   cb->ext1,
   2445                                                   cb->ext2,
   2446                                                   pme->mCallbackCookie);
   2447                                 } else {
   2448                                     ALOGE("%s : notify callback not set!",
   2449                                           __func__);
   2450                                 }
   2451                             }
   2452                             break;
   2453                         case QCAMERA_DATA_CALLBACK:
   2454                             {
   2455                                 if (pme->mDataCb) {
   2456                                     pme->mDataCb(cb->msg_type,
   2457                                                  cb->data,
   2458                                                  cb->index,
   2459                                                  cb->metadata,
   2460                                                  pme->mCallbackCookie);
   2461                                 } else {
   2462                                     ALOGE("%s : data callback not set!",
   2463                                           __func__);
   2464                                 }
   2465                             }
   2466                             break;
   2467                         case QCAMERA_DATA_TIMESTAMP_CALLBACK:
   2468                             {
   2469                                 if(pme->mDataCbTimestamp) {
   2470                                     pme->mDataCbTimestamp(cb->timestamp,
   2471                                                           cb->msg_type,
   2472                                                           cb->data,
   2473                                                           cb->index,
   2474                                                           pme->mCallbackCookie);
   2475                                 } else {
   2476                                     ALOGE("%s:data cb with tmp not set!",
   2477                                           __func__);
   2478                                 }
   2479                             }
   2480                             break;
   2481                         case QCAMERA_DATA_SNAPSHOT_CALLBACK:
   2482                             {
   2483                                 if (TRUE == isSnapshotActive && pme->mDataCb ) {
   2484                                     if (!longShotEnabled) {
   2485                                         numOfSnapshotRcvd++;
   2486                                         ALOGI("%s: [ZSL Retro] Num Snapshots Received = %d", __func__,
   2487                                                 numOfSnapshotRcvd);
   2488                                         if (numOfSnapshotExpected > 0 &&
   2489                                            (numOfSnapshotExpected == numOfSnapshotRcvd)) {
   2490                                             ALOGI("%s: [ZSL Retro] Expected snapshot received = %d",
   2491                                                     __func__, numOfSnapshotRcvd);
   2492                                             // notify HWI that snapshot is done
   2493                                             pme->mParent->processSyncEvt(QCAMERA_SM_EVT_SNAPSHOT_DONE,
   2494                                                                          NULL);
   2495                                         }
   2496                                     }
   2497                                     pme->mDataCb(cb->msg_type,
   2498                                                  cb->data,
   2499                                                  cb->index,
   2500                                                  cb->metadata,
   2501                                                  pme->mCallbackCookie);
   2502                                 }
   2503                             }
   2504                             break;
   2505                         default:
   2506                             {
   2507                                 ALOGE("%s : invalid cb type %d",
   2508                                       __func__,
   2509                                       cb->cb_type);
   2510                                 cbStatus = BAD_VALUE;
   2511                             }
   2512                             break;
   2513                         };
   2514                     } else {
   2515                         ALOGE("%s : cb message type %d not enabled!",
   2516                               __func__,
   2517                               cb->msg_type);
   2518                         cbStatus = INVALID_OPERATION;
   2519                     }
   2520                     if ( cb->release_cb ) {
   2521                         cb->release_cb(cb->user_data, cb->cookie, cbStatus);
   2522                     }
   2523                     delete cb;
   2524                 } else {
   2525                     ALOGE("%s: invalid cb type passed", __func__);
   2526                 }
   2527             }
   2528             break;
   2529         case CAMERA_CMD_TYPE_EXIT:
   2530             {
   2531                 running = 0;
   2532                 pme->mDataQ.flush();
   2533             }
   2534             break;
   2535         default:
   2536             break;
   2537         }
   2538     } while (running);
   2539     CDBG("%s: X", __func__);
   2540 
   2541     return NULL;
   2542 }
   2543 
   2544 /*===========================================================================
   2545  * FUNCTION   : notifyCallback
   2546  *
   2547  * DESCRIPTION: Enqueus pending callback notifications for the upper layers.
   2548  *
   2549  * PARAMETERS :
   2550  *   @cbArgs  : callback arguments
   2551  *
   2552  * RETURN     : int32_t type of status
   2553  *              NO_ERROR  -- success
   2554  *              none-zero failure code
   2555  *==========================================================================*/
   2556 int32_t QCameraCbNotifier::notifyCallback(qcamera_callback_argm_t &cbArgs)
   2557 {
   2558     if (!mActive) {
   2559         ALOGE("%s: notify thread is not active", __func__);
   2560         return UNKNOWN_ERROR;
   2561     }
   2562 
   2563     qcamera_callback_argm_t *cbArg = new qcamera_callback_argm_t();
   2564     if (NULL == cbArg) {
   2565         ALOGE("%s: no mem for qcamera_callback_argm_t", __func__);
   2566         return NO_MEMORY;
   2567     }
   2568     memset(cbArg, 0, sizeof(qcamera_callback_argm_t));
   2569     *cbArg = cbArgs;
   2570 
   2571     if (mDataQ.enqueue((void *)cbArg)) {
   2572         return mProcTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE);
   2573     } else {
   2574         ALOGE("%s: Error adding cb data into queue", __func__);
   2575         delete cbArg;
   2576         return UNKNOWN_ERROR;
   2577     }
   2578 }
   2579 
   2580 /*===========================================================================
   2581  * FUNCTION   : setCallbacks
   2582  *
   2583  * DESCRIPTION: Initializes the callback functions, which would be used for
   2584  *              communication with the upper layers and launches the callback
   2585  *              context in which the callbacks will occur.
   2586  *
   2587  * PARAMETERS :
   2588  *   @notifyCb          : notification callback
   2589  *   @dataCb            : data callback
   2590  *   @dataCbTimestamp   : data with timestamp callback
   2591  *   @callbackCookie    : callback context data
   2592  *
   2593  * RETURN     : None
   2594  *==========================================================================*/
   2595 void QCameraCbNotifier::setCallbacks(camera_notify_callback notifyCb,
   2596                                      camera_data_callback dataCb,
   2597                                      camera_data_timestamp_callback dataCbTimestamp,
   2598                                      void *callbackCookie)
   2599 {
   2600     if ( ( NULL == mNotifyCb ) &&
   2601          ( NULL == mDataCb ) &&
   2602          ( NULL == mDataCbTimestamp ) &&
   2603          ( NULL == mCallbackCookie ) ) {
   2604         mNotifyCb = notifyCb;
   2605         mDataCb = dataCb;
   2606         mDataCbTimestamp = dataCbTimestamp;
   2607         mCallbackCookie = callbackCookie;
   2608         mActive = true;
   2609         mProcTh.launch(cbNotifyRoutine, this);
   2610     } else {
   2611         ALOGE("%s : Camera callback notifier already initialized!",
   2612               __func__);
   2613     }
   2614 }
   2615 
   2616 /*===========================================================================
   2617  * FUNCTION   : flushPreviewNotifications
   2618  *
   2619  * DESCRIPTION: flush all pending preview notifications
   2620  *              from the notifier queue
   2621  *
   2622  * PARAMETERS : None
   2623  *
   2624  * RETURN     : int32_t type of status
   2625  *              NO_ERROR  -- success
   2626  *              none-zero failure code
   2627  *==========================================================================*/
   2628 int32_t QCameraCbNotifier::flushPreviewNotifications()
   2629 {
   2630     if (!mActive) {
   2631         ALOGE("%s: notify thread is not active", __func__);
   2632         return UNKNOWN_ERROR;
   2633     }
   2634 
   2635     mDataQ.flushNodes(matchPreviewNotifications);
   2636 
   2637     return NO_ERROR;
   2638 }
   2639 
   2640 /*===========================================================================
   2641  * FUNCTION   : startSnapshots
   2642  *
   2643  * DESCRIPTION: Enables snapshot mode
   2644  *
   2645  * PARAMETERS : None
   2646  *
   2647  * RETURN     : int32_t type of status
   2648  *              NO_ERROR  -- success
   2649  *              none-zero failure code
   2650  *==========================================================================*/
   2651 int32_t QCameraCbNotifier::startSnapshots()
   2652 {
   2653     return mProcTh.sendCmd(CAMERA_CMD_TYPE_START_DATA_PROC, FALSE, TRUE);
   2654 }
   2655 
   2656 /*===========================================================================
   2657  * FUNCTION   : stopSnapshots
   2658  *
   2659  * DESCRIPTION: Disables snapshot processing mode
   2660  *
   2661  * PARAMETERS : None
   2662  *
   2663  * RETURN     : None
   2664  *==========================================================================*/
   2665 void QCameraCbNotifier::stopSnapshots()
   2666 {
   2667     mProcTh.sendCmd(CAMERA_CMD_TYPE_STOP_DATA_PROC, FALSE, TRUE);
   2668 }
   2669 
   2670 }; // namespace qcamera
   2671