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