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  *==========================================================================*/
zsl_channel_cb(mm_camera_super_buf_t * recvd_frame,void * userdata)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  *==========================================================================*/
selectScene(QCameraChannel * pChannel,mm_camera_super_buf_t * frame)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 *==========================================================================*/
capture_channel_cb_routine(mm_camera_super_buf_t * recvd_frame,void * userdata)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 *==========================================================================*/
postproc_channel_cb_routine(mm_camera_super_buf_t * recvd_frame,void * userdata)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  *==========================================================================*/
preview_stream_cb_routine(mm_camera_super_buf_t * super_frame,QCameraStream * stream,void * userdata)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  *==========================================================================*/
sendPreviewCallback(QCameraStream * stream,QCameraGrallocMemory * memory,int32_t idx)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  *==========================================================================*/
nodisplay_preview_stream_cb_routine(mm_camera_super_buf_t * super_frame,QCameraStream * stream,void * userdata)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  *==========================================================================*/
rdi_mode_stream_cb_routine(mm_camera_super_buf_t * super_frame,QCameraStream * stream,void * userdata)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  *==========================================================================*/
postview_stream_cb_routine(mm_camera_super_buf_t * super_frame,QCameraStream * stream,void * userdata)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  *==========================================================================*/
video_stream_cb_routine(mm_camera_super_buf_t * super_frame,QCameraStream * stream,void * userdata)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  *==========================================================================*/
snapshot_stream_cb_routine(mm_camera_super_buf_t * super_frame,QCameraStream *,void * userdata)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  *==========================================================================*/
raw_stream_cb_routine(mm_camera_super_buf_t * super_frame,QCameraStream *,void * userdata)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  *==========================================================================*/
preview_raw_stream_cb_routine(mm_camera_super_buf_t * super_frame,QCameraStream * stream,void * userdata)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  *==========================================================================*/
snapshot_raw_stream_cb_routine(mm_camera_super_buf_t * super_frame,QCameraStream * stream,void * userdata)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  *==========================================================================*/
metadata_stream_cb_routine(mm_camera_super_buf_t * super_frame,QCameraStream * stream,void * userdata)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  *==========================================================================*/
reprocess_stream_cb_routine(mm_camera_super_buf_t * super_frame,QCameraStream *,void * userdata)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  *==========================================================================*/
dumpJpegToFile(const void * data,uint32_t size,int index)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 
dumpMetadataToFile(QCameraStream * stream,mm_camera_buf_def_t * frame,char * type)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  *==========================================================================*/
dumpFrameToFile(QCameraStream * stream,mm_camera_buf_def_t * frame,int dump_type)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  *==========================================================================*/
debugShowVideoFPS()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  *==========================================================================*/
debugShowPreviewFPS()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  *==========================================================================*/
~QCameraCbNotifier()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  *==========================================================================*/
exit()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  *==========================================================================*/
releaseNotifications(void * data,void * user_data)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  *==========================================================================*/
matchSnapshotNotifications(void * data,void *)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  *==========================================================================*/
cbNotifyRoutine(void * data)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  *==========================================================================*/
notifyCallback(qcamera_callback_argm_t & cbArgs)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  *==========================================================================*/
setCallbacks(camera_notify_callback notifyCb,camera_data_callback dataCb,camera_data_timestamp_callback dataCbTimestamp,void * callbackCookie)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  *==========================================================================*/
startSnapshots()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  *==========================================================================*/
stopSnapshots()2203 void QCameraCbNotifier::stopSnapshots()
2204 {
2205     mProcTh.sendCmd(CAMERA_CMD_TYPE_STOP_DATA_PROC, FALSE, TRUE);
2206 }
2207 
2208 }; // namespace qcamera
2209