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