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     if (pMetaData == NULL) {
   1438         ALOGE("%s: Null Metadata buffer", __func__);
   1439         return rc;
   1440     }
   1441 
   1442     // Sharpness
   1443     cam_edge_application_t edge_application;
   1444     memset(&edge_application, 0x00, sizeof(cam_edge_application_t));
   1445     edge_application.sharpness = mParameters.getSharpness();
   1446     if (edge_application.sharpness != 0) {
   1447         edge_application.edge_mode = CAM_EDGE_MODE_FAST;
   1448     } else {
   1449         edge_application.edge_mode = CAM_EDGE_MODE_OFF;
   1450     }
   1451     ADD_SET_PARAM_ENTRY_TO_BATCH(pMetaData,
   1452             CAM_INTF_META_EDGE_MODE, edge_application);
   1453 
   1454     //Effect
   1455     int32_t prmEffect = mParameters.getEffect();
   1456     ADD_SET_PARAM_ENTRY_TO_BATCH(pMetaData, CAM_INTF_PARM_EFFECT, prmEffect);
   1457 
   1458     //flip
   1459     int32_t prmFlip = mParameters.getFlipMode(CAM_STREAM_TYPE_SNAPSHOT);
   1460     ADD_SET_PARAM_ENTRY_TO_BATCH(pMetaData, CAM_INTF_PARM_FLIP, prmFlip);
   1461 
   1462     //denoise
   1463     uint8_t prmDenoise = (uint8_t)mParameters.isWNREnabled();
   1464     ADD_SET_PARAM_ENTRY_TO_BATCH(pMetaData,
   1465             CAM_INTF_META_NOISE_REDUCTION_MODE, prmDenoise);
   1466 
   1467     //rotation & device rotation
   1468     uint32_t prmRotation = mParameters.getJpegRotation();
   1469     cam_rotation_info_t rotation_info;
   1470     if (prmRotation == 0) {
   1471        rotation_info.rotation = ROTATE_0;
   1472     } else if (prmRotation == 90) {
   1473        rotation_info.rotation = ROTATE_90;
   1474     } else if (prmRotation == 180) {
   1475        rotation_info.rotation = ROTATE_180;
   1476     } else if (prmRotation == 270) {
   1477        rotation_info.rotation = ROTATE_270;
   1478     }
   1479 
   1480     uint32_t device_rotation = mParameters.getDeviceRotation();
   1481     if (device_rotation == 0) {
   1482         rotation_info.device_rotation = ROTATE_0;
   1483     } else if (device_rotation == 90) {
   1484         rotation_info.device_rotation = ROTATE_90;
   1485     } else if (device_rotation == 180) {
   1486         rotation_info.device_rotation = ROTATE_180;
   1487     } else if (device_rotation == 270) {
   1488         rotation_info.device_rotation = ROTATE_270;
   1489     } else {
   1490         rotation_info.device_rotation = ROTATE_0;
   1491     }
   1492     ADD_SET_PARAM_ENTRY_TO_BATCH(pMetaData, CAM_INTF_PARM_ROTATION, rotation_info);
   1493 
   1494     return rc;
   1495 }
   1496 
   1497 /*===========================================================================
   1498  * FUNCTION   : metadata_stream_cb_routine
   1499  *
   1500  * DESCRIPTION: helper function to handle metadata frame from metadata stream
   1501  *
   1502  * PARAMETERS :
   1503  *   @super_frame : received super buffer
   1504  *   @stream      : stream object
   1505  *   @userdata    : user data ptr
   1506  *
   1507  * RETURN    : None
   1508  *
   1509  * NOTE      : caller passes the ownership of super_frame, it's our
   1510  *             responsibility to free super_frame once it's done. Metadata
   1511  *             could have valid entries for face detection result or
   1512  *             histogram statistics information.
   1513  *==========================================================================*/
   1514 void QCamera2HardwareInterface::metadata_stream_cb_routine(mm_camera_super_buf_t * super_frame,
   1515                                                            QCameraStream * stream,
   1516                                                            void * userdata)
   1517 {
   1518     ATRACE_CALL();
   1519     CDBG("[KPI Perf] %s : BEGIN", __func__);
   1520     QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata;
   1521     if (pme == NULL ||
   1522         pme->mCameraHandle == NULL ||
   1523         pme->mCameraHandle->camera_handle != super_frame->camera_handle){
   1524         ALOGE("%s: camera obj not valid", __func__);
   1525         // simply free super frame
   1526         free(super_frame);
   1527         return;
   1528     }
   1529 
   1530     mm_camera_buf_def_t *frame = super_frame->bufs[0];
   1531     metadata_buffer_t *pMetaData = (metadata_buffer_t *)frame->buffer;
   1532     if(pme->m_stateMachine.isNonZSLCaptureRunning()&&
   1533        !pme->mLongshotEnabled) {
   1534        //Make shutter call back in non ZSL mode once raw frame is received from VFE.
   1535        pme->playShutter();
   1536     }
   1537 
   1538     if (pMetaData->is_tuning_params_valid && pme->mParameters.getRecordingHintValue() == true) {
   1539         //Dump Tuning data for video
   1540         pme->dumpMetadataToFile(stream,frame,(char *)"Video");
   1541     }
   1542 
   1543     IF_META_AVAILABLE(cam_hist_stats_t, stats_data, CAM_INTF_META_HISTOGRAM, pMetaData) {
   1544         // process histogram statistics info
   1545         qcamera_sm_internal_evt_payload_t *payload =
   1546             (qcamera_sm_internal_evt_payload_t *)
   1547                 malloc(sizeof(qcamera_sm_internal_evt_payload_t));
   1548         if (NULL != payload) {
   1549             memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
   1550             payload->evt_type = QCAMERA_INTERNAL_EVT_HISTOGRAM_STATS;
   1551             payload->stats_data = *stats_data;
   1552             int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
   1553             if (rc != NO_ERROR) {
   1554                 ALOGE("%s: processEvt histogram failed", __func__);
   1555                 free(payload);
   1556                 payload = NULL;
   1557 
   1558             }
   1559         } else {
   1560             ALOGE("%s: No memory for histogram qcamera_sm_internal_evt_payload_t", __func__);
   1561         }
   1562     }
   1563 
   1564     IF_META_AVAILABLE(cam_face_detection_data_t, faces_data,
   1565             CAM_INTF_META_FACE_DETECTION, pMetaData) {
   1566         if (faces_data->num_faces_detected > MAX_ROI) {
   1567             ALOGE("%s: Invalid number of faces %d",
   1568                 __func__, faces_data->num_faces_detected);
   1569         } else {
   1570             // process face detection result
   1571             if (faces_data->num_faces_detected)
   1572                 CDBG_HIGH("[KPI Perf] %s: PROFILE_NUMBER_OF_FACES_DETECTED %d",
   1573                     __func__,faces_data->num_faces_detected);
   1574             faces_data->fd_type = QCAMERA_FD_PREVIEW; //HARD CODE here before MCT can support
   1575             qcamera_sm_internal_evt_payload_t *payload = (qcamera_sm_internal_evt_payload_t *)
   1576                 malloc(sizeof(qcamera_sm_internal_evt_payload_t));
   1577             if (NULL != payload) {
   1578                 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
   1579                 payload->evt_type = QCAMERA_INTERNAL_EVT_FACE_DETECT_RESULT;
   1580                 payload->faces_data = *faces_data;
   1581                 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
   1582                 if (rc != NO_ERROR) {
   1583                     ALOGE("%s: processEvt face detection failed", __func__);
   1584                     free(payload);
   1585                     payload = NULL;
   1586                 }
   1587             } else {
   1588                 ALOGE("%s: No memory for face detect qcamera_sm_internal_evt_payload_t", __func__);
   1589             }
   1590         }
   1591     }
   1592 
   1593     IF_META_AVAILABLE(cam_auto_focus_data_t, focus_data,
   1594             CAM_INTF_META_AUTOFOCUS_DATA, pMetaData) {
   1595         qcamera_sm_internal_evt_payload_t *payload =
   1596             (qcamera_sm_internal_evt_payload_t *)malloc(sizeof(qcamera_sm_internal_evt_payload_t));
   1597         if (NULL != payload) {
   1598             memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
   1599             payload->evt_type = QCAMERA_INTERNAL_EVT_FOCUS_UPDATE;
   1600             payload->focus_data = *focus_data;
   1601             payload->focus_data.focused_frame_idx = frame->frame_idx;
   1602             int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
   1603             if (rc != NO_ERROR) {
   1604                 ALOGE("%s: processEvt focus failed", __func__);
   1605                 free(payload);
   1606                 payload = NULL;
   1607 
   1608             }
   1609         } else {
   1610             ALOGE("%s: No memory for focus qcamera_sm_internal_evt_payload_t", __func__);
   1611         }
   1612     }
   1613 
   1614     IF_META_AVAILABLE(cam_crop_data_t, crop_data, CAM_INTF_META_CROP_DATA, pMetaData) {
   1615         if (crop_data->num_of_streams > MAX_NUM_STREAMS) {
   1616             ALOGE("%s: Invalid num_of_streams %d in crop_data", __func__,
   1617                 crop_data->num_of_streams);
   1618         } else {
   1619             qcamera_sm_internal_evt_payload_t *payload =
   1620                 (qcamera_sm_internal_evt_payload_t *)
   1621                     malloc(sizeof(qcamera_sm_internal_evt_payload_t));
   1622             if (NULL != payload) {
   1623                 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
   1624                 payload->evt_type = QCAMERA_INTERNAL_EVT_CROP_INFO;
   1625                 payload->crop_data = *crop_data;
   1626                 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
   1627                 if (rc != NO_ERROR) {
   1628                     ALOGE("%s: processEvt crop info failed", __func__);
   1629                     free(payload);
   1630                     payload = NULL;
   1631 
   1632                 }
   1633             } else {
   1634                 ALOGE("%s: No memory for prep_snapshot qcamera_sm_internal_evt_payload_t",
   1635                     __func__);
   1636             }
   1637         }
   1638     }
   1639 
   1640     IF_META_AVAILABLE(int32_t, prep_snapshot_done_state,
   1641             CAM_INTF_META_PREP_SNAPSHOT_DONE, pMetaData) {
   1642         qcamera_sm_internal_evt_payload_t *payload =
   1643         (qcamera_sm_internal_evt_payload_t *)malloc(sizeof(qcamera_sm_internal_evt_payload_t));
   1644         if (NULL != payload) {
   1645             memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
   1646             payload->evt_type = QCAMERA_INTERNAL_EVT_PREP_SNAPSHOT_DONE;
   1647             payload->prep_snapshot_state = (cam_prep_snapshot_state_t)*prep_snapshot_done_state;
   1648             int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
   1649             if (rc != NO_ERROR) {
   1650                 ALOGE("%s: processEvt prep_snapshot failed", __func__);
   1651                 free(payload);
   1652                 payload = NULL;
   1653 
   1654             }
   1655         } else {
   1656             ALOGE("%s: No memory for prep_snapshot qcamera_sm_internal_evt_payload_t", __func__);
   1657         }
   1658     }
   1659 
   1660     IF_META_AVAILABLE(cam_asd_hdr_scene_data_t, hdr_scene_data,
   1661             CAM_INTF_META_ASD_HDR_SCENE_DATA, pMetaData) {
   1662         CDBG_HIGH("%s: hdr_scene_data: %d %f\n", __func__,
   1663                 hdr_scene_data->is_hdr_scene, hdr_scene_data->hdr_confidence);
   1664         //Handle this HDR meta data only if capture is not in process
   1665         if (!pme->m_stateMachine.isCaptureRunning()) {
   1666             qcamera_sm_internal_evt_payload_t *payload =
   1667                     (qcamera_sm_internal_evt_payload_t *)
   1668                     malloc(sizeof(qcamera_sm_internal_evt_payload_t));
   1669             if (NULL != payload) {
   1670                 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
   1671                 payload->evt_type = QCAMERA_INTERNAL_EVT_HDR_UPDATE;
   1672                 payload->hdr_data = *hdr_scene_data;
   1673                 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
   1674                 if (rc != NO_ERROR) {
   1675                     ALOGE("%s: processEvt hdr update failed", __func__);
   1676                     free(payload);
   1677                     payload = NULL;
   1678                 }
   1679             } else {
   1680                 ALOGE("%s: No memory for hdr update qcamera_sm_internal_evt_payload_t",
   1681                         __func__);
   1682             }
   1683         }
   1684     }
   1685 
   1686     IF_META_AVAILABLE(int32_t, scene, CAM_INTF_META_ASD_SCENE_TYPE, pMetaData) {
   1687         qcamera_sm_internal_evt_payload_t *payload =
   1688             (qcamera_sm_internal_evt_payload_t *)malloc(sizeof(qcamera_sm_internal_evt_payload_t));
   1689         if (NULL != payload) {
   1690             memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
   1691             payload->evt_type = QCAMERA_INTERNAL_EVT_ASD_UPDATE;
   1692             payload->asd_data = (cam_auto_scene_t)*scene;
   1693             int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
   1694             if (rc != NO_ERROR) {
   1695                 ALOGE("%s: processEvt asd_update failed", __func__);
   1696                 free(payload);
   1697                 payload = NULL;
   1698             }
   1699         } else {
   1700             ALOGE("%s: No memory for asd_update qcamera_sm_internal_evt_payload_t", __func__);
   1701         }
   1702     }
   1703 
   1704     IF_META_AVAILABLE(cam_awb_params_t, awb_params, CAM_INTF_META_AWB_INFO, pMetaData) {
   1705         CDBG_HIGH("%s, metadata for awb params.", __func__);
   1706         qcamera_sm_internal_evt_payload_t *payload =
   1707                 (qcamera_sm_internal_evt_payload_t *)
   1708                 malloc(sizeof(qcamera_sm_internal_evt_payload_t));
   1709         if (NULL != payload) {
   1710             memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
   1711             payload->evt_type = QCAMERA_INTERNAL_EVT_AWB_UPDATE;
   1712             payload->awb_data = *awb_params;
   1713             int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
   1714             if (rc != NO_ERROR) {
   1715                 ALOGE("%s: processEvt awb_update failed", __func__);
   1716                 free(payload);
   1717                 payload = NULL;
   1718             }
   1719         } else {
   1720             ALOGE("%s: No memory for awb_update qcamera_sm_internal_evt_payload_t", __func__);
   1721         }
   1722     }
   1723 
   1724     IF_META_AVAILABLE(uint32_t, flash_mode, CAM_INTF_META_FLASH_MODE, pMetaData) {
   1725         pme->mExifParams.sensor_params.flash_mode = (cam_flash_mode_t)*flash_mode;
   1726     }
   1727 
   1728     IF_META_AVAILABLE(int32_t, flash_state, CAM_INTF_META_FLASH_STATE, pMetaData) {
   1729         pme->mExifParams.sensor_params.flash_state = (cam_flash_state_t) *flash_state;
   1730     }
   1731 
   1732     IF_META_AVAILABLE(float, aperture_value, CAM_INTF_META_LENS_APERTURE, pMetaData) {
   1733         pme->mExifParams.sensor_params.aperture_value = *aperture_value;
   1734     }
   1735 
   1736     IF_META_AVAILABLE(cam_3a_params_t, ae_params, CAM_INTF_META_AEC_INFO, pMetaData) {
   1737         pme->mExifParams.cam_3a_params = *ae_params;
   1738         pme->mExifParams.cam_3a_params_valid = TRUE;
   1739         pme->mFlashNeeded = ae_params->flash_needed;
   1740         pme->mExifParams.cam_3a_params.brightness = (float) pme->mParameters.getBrightness();
   1741         qcamera_sm_internal_evt_payload_t *payload =
   1742                 (qcamera_sm_internal_evt_payload_t *)
   1743                 malloc(sizeof(qcamera_sm_internal_evt_payload_t));
   1744         if (NULL != payload) {
   1745             memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
   1746             payload->evt_type = QCAMERA_INTERNAL_EVT_AE_UPDATE;
   1747             payload->ae_data = *ae_params;
   1748             int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
   1749             if (rc != NO_ERROR) {
   1750                 ALOGE("%s: processEvt ae_update failed", __func__);
   1751                 free(payload);
   1752                 payload = NULL;
   1753             }
   1754         } else {
   1755             ALOGE("%s: No memory for ae_update qcamera_sm_internal_evt_payload_t", __func__);
   1756         }
   1757     }
   1758 
   1759     IF_META_AVAILABLE(int32_t, wb_mode, CAM_INTF_PARM_WHITE_BALANCE, pMetaData) {
   1760         pme->mExifParams.cam_3a_params.wb_mode = (cam_wb_mode_type) *wb_mode;
   1761     }
   1762 
   1763     IF_META_AVAILABLE(cam_sensor_params_t, sensor_params, CAM_INTF_META_SENSOR_INFO, pMetaData) {
   1764         pme->mExifParams.sensor_params = *sensor_params;
   1765     }
   1766 
   1767     IF_META_AVAILABLE(cam_ae_exif_debug_t, ae_exif_debug_params,
   1768             CAM_INTF_META_EXIF_DEBUG_AE, pMetaData) {
   1769         pme->mExifParams.ae_debug_params = *ae_exif_debug_params;
   1770         pme->mExifParams.ae_debug_params_valid = TRUE;
   1771     }
   1772 
   1773     IF_META_AVAILABLE(cam_awb_exif_debug_t, awb_exif_debug_params,
   1774             CAM_INTF_META_EXIF_DEBUG_AWB, pMetaData) {
   1775         pme->mExifParams.awb_debug_params = *awb_exif_debug_params;
   1776         pme->mExifParams.awb_debug_params_valid = TRUE;
   1777     }
   1778 
   1779     IF_META_AVAILABLE(cam_af_exif_debug_t, af_exif_debug_params,
   1780             CAM_INTF_META_EXIF_DEBUG_AF, pMetaData) {
   1781         pme->mExifParams.af_debug_params = *af_exif_debug_params;
   1782         pme->mExifParams.af_debug_params_valid = TRUE;
   1783     }
   1784 
   1785     IF_META_AVAILABLE(cam_asd_exif_debug_t, asd_exif_debug_params,
   1786             CAM_INTF_META_EXIF_DEBUG_ASD, pMetaData) {
   1787         pme->mExifParams.asd_debug_params = *asd_exif_debug_params;
   1788         pme->mExifParams.asd_debug_params_valid = TRUE;
   1789     }
   1790 
   1791     IF_META_AVAILABLE(cam_stats_buffer_exif_debug_t, stats_exif_debug_params,
   1792             CAM_INTF_META_EXIF_DEBUG_STATS, pMetaData) {
   1793         pme->mExifParams.stats_debug_params = *stats_exif_debug_params;
   1794         pme->mExifParams.stats_debug_params_valid = TRUE;
   1795     }
   1796 
   1797     IF_META_AVAILABLE(uint32_t, led_mode, CAM_INTF_META_LED_MODE_OVERRIDE, pMetaData) {
   1798         qcamera_sm_internal_evt_payload_t *payload =
   1799                 (qcamera_sm_internal_evt_payload_t *)
   1800                 malloc(sizeof(qcamera_sm_internal_evt_payload_t));
   1801         if (NULL != payload) {
   1802             memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
   1803             payload->evt_type = QCAMERA_INTERNAL_EVT_LED_MODE_OVERRIDE;
   1804             payload->led_data = (cam_flash_mode_t)*led_mode;
   1805             int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
   1806             if (rc != NO_ERROR) {
   1807                 ALOGE("%s: processEvt led mode override failed", __func__);
   1808                 free(payload);
   1809                 payload = NULL;
   1810             }
   1811         } else {
   1812             ALOGE("%s: No memory for focus qcamera_sm_internal_evt_payload_t", __func__);
   1813         }
   1814     }
   1815 
   1816     cam_edge_application_t edge_application;
   1817     memset(&edge_application, 0x00, sizeof(cam_edge_application_t));
   1818     edge_application.sharpness = pme->mParameters.getSharpness();
   1819     if (edge_application.sharpness != 0) {
   1820         edge_application.edge_mode = CAM_EDGE_MODE_FAST;
   1821     } else {
   1822         edge_application.edge_mode = CAM_EDGE_MODE_OFF;
   1823     }
   1824     ADD_SET_PARAM_ENTRY_TO_BATCH(pMetaData, CAM_INTF_META_EDGE_MODE, edge_application);
   1825 
   1826     IF_META_AVAILABLE(cam_focus_pos_info_t, cur_pos_info,
   1827             CAM_INTF_META_FOCUS_POSITION, pMetaData) {
   1828         qcamera_sm_internal_evt_payload_t *payload =
   1829             (qcamera_sm_internal_evt_payload_t *)malloc(sizeof(qcamera_sm_internal_evt_payload_t));
   1830         if (NULL != payload) {
   1831             memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
   1832             payload->evt_type = QCAMERA_INTERNAL_EVT_FOCUS_POS_UPDATE;
   1833             payload->focus_pos = *cur_pos_info;
   1834             int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
   1835             if (rc != NO_ERROR) {
   1836                 ALOGE("%s: processEvt focus_pos_update failed", __func__);
   1837                 free(payload);
   1838                 payload = NULL;
   1839             }
   1840         } else {
   1841             ALOGE("%s: No memory for focus_pos_update qcamera_sm_internal_evt_payload_t", __func__);
   1842         }
   1843     }
   1844 
   1845     stream->bufDone(frame->buf_idx);
   1846     free(super_frame);
   1847 
   1848     CDBG("[KPI Perf] %s : END", __func__);
   1849 }
   1850 
   1851 /*===========================================================================
   1852  * FUNCTION   : reprocess_stream_cb_routine
   1853  *
   1854  * DESCRIPTION: helper function to handle reprocess frame from reprocess stream
   1855                 (after reprocess, e.g., ZSL snapshot frame after WNR if
   1856  *              WNR is enabled)
   1857  *
   1858  * PARAMETERS :
   1859  *   @super_frame : received super buffer
   1860  *   @stream      : stream object
   1861  *   @userdata    : user data ptr
   1862  *
   1863  * RETURN    : None
   1864  *
   1865  * NOTE      : caller passes the ownership of super_frame, it's our
   1866  *             responsibility to free super_frame once it's done. In this
   1867  *             case, reprocessed frame need to be passed to postprocessor
   1868  *             for jpeg encoding.
   1869  *==========================================================================*/
   1870 void QCamera2HardwareInterface::reprocess_stream_cb_routine(mm_camera_super_buf_t * super_frame,
   1871                                                             QCameraStream * /*stream*/,
   1872                                                             void * userdata)
   1873 {
   1874     ATRACE_CALL();
   1875     CDBG_HIGH("[KPI Perf] %s: E", __func__);
   1876     QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata;
   1877     if (pme == NULL ||
   1878         pme->mCameraHandle == NULL ||
   1879         pme->mCameraHandle->camera_handle != super_frame->camera_handle){
   1880         ALOGE("%s: camera obj not valid", __func__);
   1881         // simply free super frame
   1882         free(super_frame);
   1883         return;
   1884     }
   1885 
   1886     pme->m_postprocessor.processPPData(super_frame);
   1887 
   1888     CDBG_HIGH("[KPI Perf] %s: X", __func__);
   1889 }
   1890 
   1891 /*===========================================================================
   1892  * FUNCTION   : dumpFrameToFile
   1893  *
   1894  * DESCRIPTION: helper function to dump jpeg into file for debug purpose.
   1895  *
   1896  * PARAMETERS :
   1897  *    @data : data ptr
   1898  *    @size : length of data buffer
   1899  *    @index : identifier for data
   1900  *
   1901  * RETURN     : None
   1902  *==========================================================================*/
   1903 void QCamera2HardwareInterface::dumpJpegToFile(const void *data,
   1904         size_t size, uint32_t index)
   1905 {
   1906     char value[PROPERTY_VALUE_MAX];
   1907     property_get("persist.camera.dumpimg", value, "0");
   1908     uint32_t enabled = (uint32_t) atoi(value);
   1909     uint32_t frm_num = 0;
   1910     uint32_t skip_mode = 0;
   1911 
   1912     char buf[32];
   1913     cam_dimension_t dim;
   1914     memset(buf, 0, sizeof(buf));
   1915     memset(&dim, 0, sizeof(dim));
   1916 
   1917     if(((enabled & QCAMERA_DUMP_FRM_JPEG) && data) ||
   1918         ((true == m_bIntJpegEvtPending) && data)) {
   1919         frm_num = ((enabled & 0xffff0000) >> 16);
   1920         if(frm_num == 0) {
   1921             frm_num = 10; //default 10 frames
   1922         }
   1923         if(frm_num > 256) {
   1924             frm_num = 256; //256 buffers cycle around
   1925         }
   1926         skip_mode = ((enabled & 0x0000ff00) >> 8);
   1927         if(skip_mode == 0) {
   1928             skip_mode = 1; //no-skip
   1929         }
   1930 
   1931         if( mDumpSkipCnt % skip_mode == 0) {
   1932             if((frm_num == 256) && (mDumpFrmCnt >= frm_num)) {
   1933                 // reset frame count if cycling
   1934                 mDumpFrmCnt = 0;
   1935             }
   1936             if (mDumpFrmCnt <= frm_num) {
   1937                 snprintf(buf, sizeof(buf), QCAMERA_DUMP_FRM_LOCATION "%d_%d.jpg",
   1938                         mDumpFrmCnt, index);
   1939                 if (true == m_bIntJpegEvtPending) {
   1940                     strlcpy(m_BackendFileName, buf, sizeof(buf));
   1941                     mBackendFileSize = size;
   1942                 }
   1943 
   1944                 int file_fd = open(buf, O_RDWR | O_CREAT, 0777);
   1945                 if (file_fd >= 0) {
   1946                     ssize_t written_len = write(file_fd, data, size);
   1947                     fchmod(file_fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
   1948                     CDBG_HIGH("%s: written number of bytes %zd\n",
   1949                             __func__, written_len);
   1950                     close(file_fd);
   1951                 } else {
   1952                     ALOGE("%s: fail t open file for image dumping", __func__);
   1953                 }
   1954                 if (false == m_bIntJpegEvtPending) {
   1955                     mDumpFrmCnt++;
   1956                 }
   1957             }
   1958         }
   1959         mDumpSkipCnt++;
   1960     }
   1961 }
   1962 
   1963 
   1964 void QCamera2HardwareInterface::dumpMetadataToFile(QCameraStream *stream,
   1965                                                    mm_camera_buf_def_t *frame,char *type)
   1966 {
   1967     char value[PROPERTY_VALUE_MAX];
   1968     uint32_t frm_num = 0;
   1969     metadata_buffer_t *metadata = (metadata_buffer_t *)frame->buffer;
   1970     property_get("persist.camera.dumpmetadata", value, "0");
   1971     uint32_t enabled = (uint32_t) atoi(value);
   1972     if (stream == NULL) {
   1973         CDBG_HIGH("No op");
   1974         return;
   1975     }
   1976 
   1977     uint32_t dumpFrmCnt = stream->mDumpMetaFrame;
   1978     if(enabled){
   1979         frm_num = ((enabled & 0xffff0000) >> 16);
   1980         if (frm_num == 0) {
   1981             frm_num = 10; //default 10 frames
   1982         }
   1983         if (frm_num > 256) {
   1984             frm_num = 256; //256 buffers cycle around
   1985         }
   1986         if ((frm_num == 256) && (dumpFrmCnt >= frm_num)) {
   1987             // reset frame count if cycling
   1988             dumpFrmCnt = 0;
   1989         }
   1990         CDBG_HIGH("dumpFrmCnt= %u, frm_num = %u", dumpFrmCnt, frm_num);
   1991         if (dumpFrmCnt < frm_num) {
   1992             char timeBuf[128];
   1993             char buf[32];
   1994             memset(buf, 0, sizeof(buf));
   1995             memset(timeBuf, 0, sizeof(timeBuf));
   1996             time_t current_time;
   1997             struct tm * timeinfo;
   1998             time (&current_time);
   1999             timeinfo = localtime (&current_time);
   2000             if (NULL != timeinfo) {
   2001                 strftime(timeBuf, sizeof(timeBuf),
   2002                         QCAMERA_DUMP_FRM_LOCATION "%Y%m%d%H%M%S", timeinfo);
   2003             }
   2004             String8 filePath(timeBuf);
   2005             snprintf(buf, sizeof(buf), "%um_%s_%d.bin", dumpFrmCnt, type, frame->frame_idx);
   2006             filePath.append(buf);
   2007             int file_fd = open(filePath.string(), O_RDWR | O_CREAT, 0777);
   2008             if (file_fd >= 0) {
   2009                 ssize_t written_len = 0;
   2010                 metadata->tuning_params.tuning_data_version = TUNING_DATA_VERSION;
   2011                 void *data = (void *)((uint8_t *)&metadata->tuning_params.tuning_data_version);
   2012                 written_len += write(file_fd, data, sizeof(uint32_t));
   2013                 data = (void *)((uint8_t *)&metadata->tuning_params.tuning_sensor_data_size);
   2014                 CDBG_HIGH("tuning_sensor_data_size %d",(int)(*(int *)data));
   2015                 written_len += write(file_fd, data, sizeof(uint32_t));
   2016                 data = (void *)((uint8_t *)&metadata->tuning_params.tuning_vfe_data_size);
   2017                 CDBG_HIGH("tuning_vfe_data_size %d",(int)(*(int *)data));
   2018                 written_len += write(file_fd, data, sizeof(uint32_t));
   2019                 data = (void *)((uint8_t *)&metadata->tuning_params.tuning_cpp_data_size);
   2020                 CDBG_HIGH("tuning_cpp_data_size %d",(int)(*(int *)data));
   2021                 written_len += write(file_fd, data, sizeof(uint32_t));
   2022                 data = (void *)((uint8_t *)&metadata->tuning_params.tuning_cac_data_size);
   2023                 CDBG_HIGH("tuning_cac_data_size %d",(int)(*(int *)data));
   2024                 written_len += write(file_fd, data, sizeof(uint32_t));
   2025                 data = (void *)((uint8_t *)&metadata->tuning_params.tuning_cac_data_size2);
   2026                 CDBG_HIGH("%s < skrajago >tuning_cac_data_size %d",__func__,(int)(*(int *)data));
   2027                 written_len += write(file_fd, data, sizeof(uint32_t));
   2028                 size_t total_size = metadata->tuning_params.tuning_sensor_data_size;
   2029                 data = (void *)((uint8_t *)&metadata->tuning_params.data);
   2030                 written_len += write(file_fd, data, total_size);
   2031                 total_size = metadata->tuning_params.tuning_vfe_data_size;
   2032                 data = (void *)((uint8_t *)&metadata->tuning_params.data[TUNING_VFE_DATA_OFFSET]);
   2033                 written_len += write(file_fd, data, total_size);
   2034                 total_size = metadata->tuning_params.tuning_cpp_data_size;
   2035                 data = (void *)((uint8_t *)&metadata->tuning_params.data[TUNING_CPP_DATA_OFFSET]);
   2036                 written_len += write(file_fd, data, total_size);
   2037                 total_size = metadata->tuning_params.tuning_cac_data_size;
   2038                 data = (void *)((uint8_t *)&metadata->tuning_params.data[TUNING_CAC_DATA_OFFSET]);
   2039                 written_len += write(file_fd, data, total_size);
   2040                 close(file_fd);
   2041             }else {
   2042                 ALOGE("%s: fail t open file for image dumping", __func__);
   2043             }
   2044             dumpFrmCnt++;
   2045         }
   2046     }
   2047     stream->mDumpMetaFrame = dumpFrmCnt;
   2048 }
   2049 /*===========================================================================
   2050  * FUNCTION   : dumpFrameToFile
   2051  *
   2052  * DESCRIPTION: helper function to dump frame into file for debug purpose.
   2053  *
   2054  * PARAMETERS :
   2055  *    @data : data ptr
   2056  *    @size : length of data buffer
   2057  *    @index : identifier for data
   2058  *    @dump_type : type of the frame to be dumped. Only such
   2059  *                 dump type is enabled, the frame will be
   2060  *                 dumped into a file.
   2061  *
   2062  * RETURN     : None
   2063  *==========================================================================*/
   2064 void QCamera2HardwareInterface::dumpFrameToFile(QCameraStream *stream,
   2065         mm_camera_buf_def_t *frame, uint32_t dump_type)
   2066 {
   2067     char value[PROPERTY_VALUE_MAX];
   2068     property_get("persist.camera.dumpimg", value, "0");
   2069     uint32_t enabled = (uint32_t) atoi(value);
   2070     uint32_t frm_num = 0;
   2071     uint32_t skip_mode = 0;
   2072 
   2073     if (NULL == stream) {
   2074         ALOGE("%s stream object is null", __func__);
   2075         return;
   2076     }
   2077 
   2078     uint32_t dumpFrmCnt = stream->mDumpFrame;
   2079 
   2080     if (true == m_bIntRawEvtPending) {
   2081         enabled = QCAMERA_DUMP_FRM_RAW;
   2082     }
   2083 
   2084     if((enabled & QCAMERA_DUMP_FRM_MASK_ALL)) {
   2085         if((enabled & dump_type) && stream && frame) {
   2086             frm_num = ((enabled & 0xffff0000) >> 16);
   2087             if(frm_num == 0) {
   2088                 frm_num = 10; //default 10 frames
   2089             }
   2090             if(frm_num > 256) {
   2091                 frm_num = 256; //256 buffers cycle around
   2092             }
   2093             skip_mode = ((enabled & 0x0000ff00) >> 8);
   2094             if(skip_mode == 0) {
   2095                 skip_mode = 1; //no-skip
   2096             }
   2097             if(stream->mDumpSkipCnt == 0)
   2098                 stream->mDumpSkipCnt = 1;
   2099 
   2100             if( stream->mDumpSkipCnt % skip_mode == 0) {
   2101                 if((frm_num == 256) && (dumpFrmCnt >= frm_num)) {
   2102                     // reset frame count if cycling
   2103                     dumpFrmCnt = 0;
   2104                 }
   2105                 if (dumpFrmCnt <= frm_num) {
   2106                     char buf[32];
   2107                     char timeBuf[128];
   2108                     time_t current_time;
   2109                     struct tm * timeinfo;
   2110 
   2111                     memset(timeBuf, 0, sizeof(timeBuf));
   2112 
   2113                     time (&current_time);
   2114                     timeinfo = localtime (&current_time);
   2115                     memset(buf, 0, sizeof(buf));
   2116 
   2117                     cam_dimension_t dim;
   2118                     memset(&dim, 0, sizeof(dim));
   2119                     stream->getFrameDimension(dim);
   2120 
   2121                     cam_frame_len_offset_t offset;
   2122                     memset(&offset, 0, sizeof(cam_frame_len_offset_t));
   2123                     stream->getFrameOffset(offset);
   2124 
   2125                     if (NULL != timeinfo) {
   2126                         strftime(timeBuf, sizeof(timeBuf),
   2127                                 QCAMERA_DUMP_FRM_LOCATION "%Y%m%d%H%M%S", timeinfo);
   2128                     }
   2129                     String8 filePath(timeBuf);
   2130                     switch (dump_type) {
   2131                     case QCAMERA_DUMP_FRM_PREVIEW:
   2132                         {
   2133                             snprintf(buf, sizeof(buf), "%dp_%dx%d_%d.yuv",
   2134                                     dumpFrmCnt, dim.width, dim.height, frame->frame_idx);
   2135                         }
   2136                         break;
   2137                     case QCAMERA_DUMP_FRM_THUMBNAIL:
   2138                         {
   2139                             snprintf(buf, sizeof(buf), "%dt_%dx%d_%d.yuv",
   2140                                     dumpFrmCnt, dim.width, dim.height, frame->frame_idx);
   2141                         }
   2142                         break;
   2143                     case QCAMERA_DUMP_FRM_SNAPSHOT:
   2144                         {
   2145                             mParameters.getStreamDimension(CAM_STREAM_TYPE_SNAPSHOT, dim);
   2146                             snprintf(buf, sizeof(buf), "%ds_%dx%d_%d.yuv",
   2147                                     dumpFrmCnt, dim.width, dim.height, frame->frame_idx);
   2148                         }
   2149                         break;
   2150                     case QCAMERA_DUMP_FRM_VIDEO:
   2151                         {
   2152                             snprintf(buf, sizeof(buf), "%dv_%dx%d_%d.yuv",
   2153                                     dumpFrmCnt, dim.width, dim.height, frame->frame_idx);
   2154                         }
   2155                         break;
   2156                     case QCAMERA_DUMP_FRM_RAW:
   2157                         {
   2158                             mParameters.getStreamDimension(CAM_STREAM_TYPE_RAW, dim);
   2159                             snprintf(buf, sizeof(buf), "%dr_%dx%d_%d.raw",
   2160                                     dumpFrmCnt, dim.width, dim.height, frame->frame_idx);
   2161                         }
   2162                         break;
   2163                     case QCAMERA_DUMP_FRM_JPEG:
   2164                         {
   2165                             mParameters.getStreamDimension(CAM_STREAM_TYPE_SNAPSHOT, dim);
   2166                             snprintf(buf, sizeof(buf), "%dj_%dx%d_%d.yuv",
   2167                                     dumpFrmCnt, dim.width, dim.height, frame->frame_idx);
   2168                         }
   2169                         break;
   2170                     default:
   2171                         ALOGE("%s: Not supported for dumping stream type %d",
   2172                               __func__, dump_type);
   2173                         return;
   2174                     }
   2175 
   2176                     filePath.append(buf);
   2177                     int file_fd = open(filePath.string(), O_RDWR | O_CREAT, 0777);
   2178                     ssize_t written_len = 0;
   2179                     if (file_fd >= 0) {
   2180                         void *data = NULL;
   2181 
   2182                         fchmod(file_fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
   2183                         for (uint32_t i = 0; i < offset.num_planes; i++) {
   2184                             uint32_t index = offset.mp[i].offset;
   2185                             if (i > 0) {
   2186                                 index += offset.mp[i-1].len;
   2187                             }
   2188                             for (int j = 0; j < offset.mp[i].height; j++) {
   2189                                 data = (void *)((uint8_t *)frame->buffer + index);
   2190                                 written_len += write(file_fd, data,
   2191                                         (size_t)offset.mp[i].width);
   2192                                 index += (uint32_t)offset.mp[i].stride;
   2193                             }
   2194                         }
   2195 
   2196                         CDBG_HIGH("%s: written number of bytes %ld\n",
   2197                             __func__, written_len);
   2198                         close(file_fd);
   2199                     } else {
   2200                         ALOGE("%s: fail t open file for image dumping", __func__);
   2201                     }
   2202                     if (true == m_bIntRawEvtPending) {
   2203                         strlcpy(m_BackendFileName, filePath.string(), QCAMERA_MAX_FILEPATH_LENGTH);
   2204                         mBackendFileSize = (size_t)written_len;
   2205                     } else {
   2206                         dumpFrmCnt++;
   2207                     }
   2208                 }
   2209             }
   2210             stream->mDumpSkipCnt++;
   2211         }
   2212     } else {
   2213         dumpFrmCnt = 0;
   2214     }
   2215     stream->mDumpFrame = dumpFrmCnt;
   2216 }
   2217 
   2218 /*===========================================================================
   2219  * FUNCTION   : debugShowVideoFPS
   2220  *
   2221  * DESCRIPTION: helper function to log video frame FPS for debug purpose.
   2222  *
   2223  * PARAMETERS : None
   2224  *
   2225  * RETURN     : None
   2226  *==========================================================================*/
   2227 void QCamera2HardwareInterface::debugShowVideoFPS()
   2228 {
   2229     mVFrameCount++;
   2230     nsecs_t now = systemTime();
   2231     nsecs_t diff = now - mVLastFpsTime;
   2232     if (diff > ms2ns(250)) {
   2233         mVFps = (((double)(mVFrameCount - mVLastFrameCount)) *
   2234                 (double)(s2ns(1))) / (double)diff;
   2235         CDBG_HIGH("Video Frames Per Second: %.4f Cam ID = %d", mVFps, mCameraId);
   2236         mVLastFpsTime = now;
   2237         mVLastFrameCount = mVFrameCount;
   2238     }
   2239 }
   2240 
   2241 /*===========================================================================
   2242  * FUNCTION   : debugShowPreviewFPS
   2243  *
   2244  * DESCRIPTION: helper function to log preview frame FPS for debug purpose.
   2245  *
   2246  * PARAMETERS : None
   2247  *
   2248  * RETURN     : None
   2249  *==========================================================================*/
   2250 void QCamera2HardwareInterface::debugShowPreviewFPS()
   2251 {
   2252     mPFrameCount++;
   2253     nsecs_t now = systemTime();
   2254     nsecs_t diff = now - mPLastFpsTime;
   2255     if (diff > ms2ns(250)) {
   2256         mPFps = (((double)(mPFrameCount - mPLastFrameCount)) *
   2257                 (double)(s2ns(1))) / (double)diff;
   2258         CDBG_HIGH("[KPI Perf] %s: PROFILE_PREVIEW_FRAMES_PER_SECOND : %.4f Cam ID = %d",
   2259                 __func__, mPFps, mCameraId);
   2260         mPLastFpsTime = now;
   2261         mPLastFrameCount = mPFrameCount;
   2262     }
   2263 }
   2264 
   2265 /*===========================================================================
   2266  * FUNCTION   : ~QCameraCbNotifier
   2267  *
   2268  * DESCRIPTION: Destructor for exiting the callback context.
   2269  *
   2270  * PARAMETERS : None
   2271  *
   2272  * RETURN     : None
   2273  *==========================================================================*/
   2274 QCameraCbNotifier::~QCameraCbNotifier()
   2275 {
   2276 }
   2277 
   2278 /*===========================================================================
   2279  * FUNCTION   : exit
   2280  *
   2281  * DESCRIPTION: exit notify thread.
   2282  *
   2283  * PARAMETERS : None
   2284  *
   2285  * RETURN     : None
   2286  *==========================================================================*/
   2287 void QCameraCbNotifier::exit()
   2288 {
   2289     mActive = false;
   2290     mProcTh.exit();
   2291 }
   2292 
   2293 /*===========================================================================
   2294  * FUNCTION   : releaseNotifications
   2295  *
   2296  * DESCRIPTION: callback for releasing data stored in the callback queue.
   2297  *
   2298  * PARAMETERS :
   2299  *   @data      : data to be released
   2300  *   @user_data : context data
   2301  *
   2302  * RETURN     : None
   2303  *==========================================================================*/
   2304 void QCameraCbNotifier::releaseNotifications(void *data, void *user_data)
   2305 {
   2306     qcamera_callback_argm_t *arg = ( qcamera_callback_argm_t * ) data;
   2307 
   2308     if ( ( NULL != arg ) && ( NULL != user_data ) ) {
   2309         if ( arg->release_cb ) {
   2310             arg->release_cb(arg->user_data, arg->cookie, FAILED_TRANSACTION);
   2311         }
   2312     }
   2313 }
   2314 
   2315 /*===========================================================================
   2316  * FUNCTION   : matchSnapshotNotifications
   2317  *
   2318  * DESCRIPTION: matches snapshot data callbacks
   2319  *
   2320  * PARAMETERS :
   2321  *   @data      : data to match
   2322  *   @user_data : context data
   2323  *
   2324  * RETURN     : bool match
   2325  *              true - match found
   2326  *              false- match not found
   2327  *==========================================================================*/
   2328 bool QCameraCbNotifier::matchSnapshotNotifications(void *data,
   2329                                                    void */*user_data*/)
   2330 {
   2331     qcamera_callback_argm_t *arg = ( qcamera_callback_argm_t * ) data;
   2332     if ( NULL != arg ) {
   2333         if ( QCAMERA_DATA_SNAPSHOT_CALLBACK == arg->cb_type ) {
   2334             return true;
   2335         }
   2336     }
   2337 
   2338     return false;
   2339 }
   2340 
   2341 /*===========================================================================
   2342  * FUNCTION   : matchPreviewNotifications
   2343  *
   2344  * DESCRIPTION: matches preview data callbacks
   2345  *
   2346  * PARAMETERS :
   2347  *   @data      : data to match
   2348  *   @user_data : context data
   2349  *
   2350  * RETURN     : bool match
   2351  *              true - match found
   2352  *              false- match not found
   2353  *==========================================================================*/
   2354 bool QCameraCbNotifier::matchPreviewNotifications(void *data,
   2355         void */*user_data*/)
   2356 {
   2357     qcamera_callback_argm_t *arg = ( qcamera_callback_argm_t * ) data;
   2358     if (NULL != arg) {
   2359         if ((QCAMERA_DATA_CALLBACK == arg->cb_type) &&
   2360                 (CAMERA_MSG_PREVIEW_FRAME == arg->msg_type)) {
   2361             return true;
   2362         }
   2363     }
   2364 
   2365     return false;
   2366 }
   2367 
   2368 /*===========================================================================
   2369  * FUNCTION   : cbNotifyRoutine
   2370  *
   2371  * DESCRIPTION: callback thread which interfaces with the upper layers
   2372  *              given input commands.
   2373  *
   2374  * PARAMETERS :
   2375  *   @data    : context data
   2376  *
   2377  * RETURN     : None
   2378  *==========================================================================*/
   2379 void * QCameraCbNotifier::cbNotifyRoutine(void * data)
   2380 {
   2381     int running = 1;
   2382     int ret;
   2383     QCameraCbNotifier *pme = (QCameraCbNotifier *)data;
   2384     QCameraCmdThread *cmdThread = &pme->mProcTh;
   2385     cmdThread->setName("CAM_cbNotify");
   2386     uint8_t isSnapshotActive = FALSE;
   2387     bool longShotEnabled = false;
   2388     uint32_t numOfSnapshotExpected = 0;
   2389     uint32_t numOfSnapshotRcvd = 0;
   2390     int32_t cbStatus = NO_ERROR;
   2391 
   2392     CDBG("%s: E", __func__);
   2393     do {
   2394         do {
   2395             ret = cam_sem_wait(&cmdThread->cmd_sem);
   2396             if (ret != 0 && errno != EINVAL) {
   2397                 CDBG("%s: cam_sem_wait error (%s)",
   2398                            __func__, strerror(errno));
   2399                 return NULL;
   2400             }
   2401         } while (ret != 0);
   2402 
   2403         camera_cmd_type_t cmd = cmdThread->getCmd();
   2404         CDBG("%s: get cmd %d", __func__, cmd);
   2405         switch (cmd) {
   2406         case CAMERA_CMD_TYPE_START_DATA_PROC:
   2407             {
   2408                 isSnapshotActive = TRUE;
   2409                 numOfSnapshotExpected = pme->mParent->numOfSnapshotsExpected();
   2410                 longShotEnabled = pme->mParent->isLongshotEnabled();
   2411                 ALOGI("%s: Num Snapshots Expected = %d",
   2412                   __func__, numOfSnapshotExpected);
   2413                 numOfSnapshotRcvd = 0;
   2414             }
   2415             break;
   2416         case CAMERA_CMD_TYPE_STOP_DATA_PROC:
   2417             {
   2418                 pme->mDataQ.flushNodes(matchSnapshotNotifications);
   2419                 isSnapshotActive = FALSE;
   2420 
   2421                 numOfSnapshotExpected = 0;
   2422                 numOfSnapshotRcvd = 0;
   2423             }
   2424             break;
   2425         case CAMERA_CMD_TYPE_DO_NEXT_JOB:
   2426             {
   2427                 qcamera_callback_argm_t *cb =
   2428                     (qcamera_callback_argm_t *)pme->mDataQ.dequeue();
   2429                 cbStatus = NO_ERROR;
   2430                 if (NULL != cb) {
   2431                     CDBG("%s: cb type %d received",
   2432                           __func__,
   2433                           cb->cb_type);
   2434 
   2435                     if (pme->mParent->msgTypeEnabledWithLock(cb->msg_type)) {
   2436                         switch (cb->cb_type) {
   2437                         case QCAMERA_NOTIFY_CALLBACK:
   2438                             {
   2439                                 if (cb->msg_type == CAMERA_MSG_FOCUS) {
   2440                                     ATRACE_INT("Camera:AutoFocus", 0);
   2441                                     CDBG_HIGH("[KPI Perf] %s : PROFILE_SENDING_FOCUS_EVT_TO APP",
   2442                                         __func__);
   2443                                 }
   2444                                 if (pme->mNotifyCb) {
   2445                                     pme->mNotifyCb(cb->msg_type,
   2446                                                   cb->ext1,
   2447                                                   cb->ext2,
   2448                                                   pme->mCallbackCookie);
   2449                                 } else {
   2450                                     ALOGE("%s : notify callback not set!",
   2451                                           __func__);
   2452                                 }
   2453                             }
   2454                             break;
   2455                         case QCAMERA_DATA_CALLBACK:
   2456                             {
   2457                                 if (pme->mDataCb) {
   2458                                     pme->mDataCb(cb->msg_type,
   2459                                                  cb->data,
   2460                                                  cb->index,
   2461                                                  cb->metadata,
   2462                                                  pme->mCallbackCookie);
   2463                                 } else {
   2464                                     ALOGE("%s : data callback not set!",
   2465                                           __func__);
   2466                                 }
   2467                             }
   2468                             break;
   2469                         case QCAMERA_DATA_TIMESTAMP_CALLBACK:
   2470                             {
   2471                                 if(pme->mDataCbTimestamp) {
   2472                                     pme->mDataCbTimestamp(cb->timestamp,
   2473                                                           cb->msg_type,
   2474                                                           cb->data,
   2475                                                           cb->index,
   2476                                                           pme->mCallbackCookie);
   2477                                 } else {
   2478                                     ALOGE("%s:data cb with tmp not set!",
   2479                                           __func__);
   2480                                 }
   2481                             }
   2482                             break;
   2483                         case QCAMERA_DATA_SNAPSHOT_CALLBACK:
   2484                             {
   2485                                 if (TRUE == isSnapshotActive && pme->mDataCb ) {
   2486                                     if (!longShotEnabled) {
   2487                                         numOfSnapshotRcvd++;
   2488                                         ALOGI("%s: [ZSL Retro] Num Snapshots Received = %d", __func__,
   2489                                                 numOfSnapshotRcvd);
   2490                                         if (numOfSnapshotExpected > 0 &&
   2491                                            (numOfSnapshotExpected == numOfSnapshotRcvd)) {
   2492                                             ALOGI("%s: [ZSL Retro] Expected snapshot received = %d",
   2493                                                     __func__, numOfSnapshotRcvd);
   2494                                             // notify HWI that snapshot is done
   2495                                             pme->mParent->processSyncEvt(QCAMERA_SM_EVT_SNAPSHOT_DONE,
   2496                                                                          NULL);
   2497                                         }
   2498                                     }
   2499                                     pme->mDataCb(cb->msg_type,
   2500                                                  cb->data,
   2501                                                  cb->index,
   2502                                                  cb->metadata,
   2503                                                  pme->mCallbackCookie);
   2504                                 }
   2505                             }
   2506                             break;
   2507                         default:
   2508                             {
   2509                                 ALOGE("%s : invalid cb type %d",
   2510                                       __func__,
   2511                                       cb->cb_type);
   2512                                 cbStatus = BAD_VALUE;
   2513                             }
   2514                             break;
   2515                         };
   2516                     } else {
   2517                         ALOGE("%s : cb message type %d not enabled!",
   2518                               __func__,
   2519                               cb->msg_type);
   2520                         cbStatus = INVALID_OPERATION;
   2521                     }
   2522                     if ( cb->release_cb ) {
   2523                         cb->release_cb(cb->user_data, cb->cookie, cbStatus);
   2524                     }
   2525                     delete cb;
   2526                 } else {
   2527                     ALOGE("%s: invalid cb type passed", __func__);
   2528                 }
   2529             }
   2530             break;
   2531         case CAMERA_CMD_TYPE_EXIT:
   2532             {
   2533                 running = 0;
   2534                 pme->mDataQ.flush();
   2535             }
   2536             break;
   2537         default:
   2538             break;
   2539         }
   2540     } while (running);
   2541     CDBG("%s: X", __func__);
   2542 
   2543     return NULL;
   2544 }
   2545 
   2546 /*===========================================================================
   2547  * FUNCTION   : notifyCallback
   2548  *
   2549  * DESCRIPTION: Enqueus pending callback notifications for the upper layers.
   2550  *
   2551  * PARAMETERS :
   2552  *   @cbArgs  : callback arguments
   2553  *
   2554  * RETURN     : int32_t type of status
   2555  *              NO_ERROR  -- success
   2556  *              none-zero failure code
   2557  *==========================================================================*/
   2558 int32_t QCameraCbNotifier::notifyCallback(qcamera_callback_argm_t &cbArgs)
   2559 {
   2560     if (!mActive) {
   2561         ALOGE("%s: notify thread is not active", __func__);
   2562         return UNKNOWN_ERROR;
   2563     }
   2564 
   2565     qcamera_callback_argm_t *cbArg = new qcamera_callback_argm_t();
   2566     if (NULL == cbArg) {
   2567         ALOGE("%s: no mem for qcamera_callback_argm_t", __func__);
   2568         return NO_MEMORY;
   2569     }
   2570     memset(cbArg, 0, sizeof(qcamera_callback_argm_t));
   2571     *cbArg = cbArgs;
   2572 
   2573     if (mDataQ.enqueue((void *)cbArg)) {
   2574         return mProcTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE);
   2575     } else {
   2576         ALOGE("%s: Error adding cb data into queue", __func__);
   2577         delete cbArg;
   2578         return UNKNOWN_ERROR;
   2579     }
   2580 }
   2581 
   2582 /*===========================================================================
   2583  * FUNCTION   : setCallbacks
   2584  *
   2585  * DESCRIPTION: Initializes the callback functions, which would be used for
   2586  *              communication with the upper layers and launches the callback
   2587  *              context in which the callbacks will occur.
   2588  *
   2589  * PARAMETERS :
   2590  *   @notifyCb          : notification callback
   2591  *   @dataCb            : data callback
   2592  *   @dataCbTimestamp   : data with timestamp callback
   2593  *   @callbackCookie    : callback context data
   2594  *
   2595  * RETURN     : None
   2596  *==========================================================================*/
   2597 void QCameraCbNotifier::setCallbacks(camera_notify_callback notifyCb,
   2598                                      camera_data_callback dataCb,
   2599                                      camera_data_timestamp_callback dataCbTimestamp,
   2600                                      void *callbackCookie)
   2601 {
   2602     if ( ( NULL == mNotifyCb ) &&
   2603          ( NULL == mDataCb ) &&
   2604          ( NULL == mDataCbTimestamp ) &&
   2605          ( NULL == mCallbackCookie ) ) {
   2606         mNotifyCb = notifyCb;
   2607         mDataCb = dataCb;
   2608         mDataCbTimestamp = dataCbTimestamp;
   2609         mCallbackCookie = callbackCookie;
   2610         mActive = true;
   2611         mProcTh.launch(cbNotifyRoutine, this);
   2612     } else {
   2613         ALOGE("%s : Camera callback notifier already initialized!",
   2614               __func__);
   2615     }
   2616 }
   2617 
   2618 /*===========================================================================
   2619  * FUNCTION   : flushPreviewNotifications
   2620  *
   2621  * DESCRIPTION: flush all pending preview notifications
   2622  *              from the notifier queue
   2623  *
   2624  * PARAMETERS : None
   2625  *
   2626  * RETURN     : int32_t type of status
   2627  *              NO_ERROR  -- success
   2628  *              none-zero failure code
   2629  *==========================================================================*/
   2630 int32_t QCameraCbNotifier::flushPreviewNotifications()
   2631 {
   2632     if (!mActive) {
   2633         ALOGE("%s: notify thread is not active", __func__);
   2634         return UNKNOWN_ERROR;
   2635     }
   2636 
   2637     mDataQ.flushNodes(matchPreviewNotifications);
   2638 
   2639     return NO_ERROR;
   2640 }
   2641 
   2642 /*===========================================================================
   2643  * FUNCTION   : startSnapshots
   2644  *
   2645  * DESCRIPTION: Enables snapshot mode
   2646  *
   2647  * PARAMETERS : None
   2648  *
   2649  * RETURN     : int32_t type of status
   2650  *              NO_ERROR  -- success
   2651  *              none-zero failure code
   2652  *==========================================================================*/
   2653 int32_t QCameraCbNotifier::startSnapshots()
   2654 {
   2655     return mProcTh.sendCmd(CAMERA_CMD_TYPE_START_DATA_PROC, FALSE, TRUE);
   2656 }
   2657 
   2658 /*===========================================================================
   2659  * FUNCTION   : stopSnapshots
   2660  *
   2661  * DESCRIPTION: Disables snapshot processing mode
   2662  *
   2663  * PARAMETERS : None
   2664  *
   2665  * RETURN     : None
   2666  *==========================================================================*/
   2667 void QCameraCbNotifier::stopSnapshots()
   2668 {
   2669     mProcTh.sendCmd(CAMERA_CMD_TYPE_STOP_DATA_PROC, FALSE, TRUE);
   2670 }
   2671 
   2672 }; // namespace qcamera
   2673