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