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 (¤t_time);
1999 timeinfo = localtime (¤t_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 (¤t_time);
2114 timeinfo = localtime (¤t_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