1 /* Copyright (c) 2012-2013, The Linux Foundataion. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30 #define LOG_TAG "QCamera2HWI"
31
32 #include <fcntl.h>
33 #include <utils/Errors.h>
34 #include <utils/Timers.h>
35 #include "QCamera2HWI.h"
36
37 namespace qcamera {
38
39 /*===========================================================================
40 * FUNCTION : zsl_channel_cb
41 *
42 * DESCRIPTION: helper function to handle ZSL superbuf callback directly from
43 * mm-camera-interface
44 *
45 * PARAMETERS :
46 * @recvd_frame : received super buffer
47 * @userdata : user data ptr
48 *
49 * RETURN : None
50 *
51 * NOTE : recvd_frame will be released after this call by caller, so if
52 * async operation needed for recvd_frame, it's our responsibility
53 * to save a copy for this variable to be used later.
54 *==========================================================================*/
zsl_channel_cb(mm_camera_super_buf_t * recvd_frame,void * userdata)55 void QCamera2HardwareInterface::zsl_channel_cb(mm_camera_super_buf_t *recvd_frame,
56 void *userdata)
57 {
58 ALOGD("[KPI Perf] %s: E",__func__);
59 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata;
60 if (pme == NULL ||
61 pme->mCameraHandle == NULL ||
62 pme->mCameraHandle->camera_handle != recvd_frame->camera_handle){
63 ALOGE("%s: camera obj not valid", __func__);
64 return;
65 }
66
67 QCameraChannel *pChannel = pme->m_channels[QCAMERA_CH_TYPE_ZSL];
68 if (pChannel == NULL ||
69 pChannel->getMyHandle() != recvd_frame->ch_id) {
70 ALOGE("%s: ZSL channel doesn't exist, return here", __func__);
71 return;
72 }
73
74 // save a copy for the superbuf
75 mm_camera_super_buf_t* frame =
76 (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t));
77 if (frame == NULL) {
78 ALOGE("%s: Error allocating memory to save received_frame structure.", __func__);
79 pChannel->bufDone(recvd_frame);
80 return;
81 }
82 *frame = *recvd_frame;
83
84 // send to postprocessor
85 pme->m_postprocessor.processData(frame);
86
87 ALOGD("[KPI Perf] %s: X", __func__);
88 }
89
90 /*===========================================================================
91 * FUNCTION : capture_channel_cb_routine
92 *
93 * DESCRIPTION: helper function to handle snapshot superbuf callback directly from
94 * mm-camera-interface
95 *
96 * PARAMETERS :
97 * @recvd_frame : received super buffer
98 * @userdata : user data ptr
99 *
100 * RETURN : None
101 *
102 * NOTE : recvd_frame will be released after this call by caller, so if
103 * async operation needed for recvd_frame, it's our responsibility
104 * to save a copy for this variable to be used later.
105 *==========================================================================*/
capture_channel_cb_routine(mm_camera_super_buf_t * recvd_frame,void * userdata)106 void QCamera2HardwareInterface::capture_channel_cb_routine(mm_camera_super_buf_t *recvd_frame,
107 void *userdata)
108 {
109 ALOGD("[KPI Perf] %s: E", __func__);
110 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata;
111 if (pme == NULL ||
112 pme->mCameraHandle == NULL ||
113 pme->mCameraHandle->camera_handle != recvd_frame->camera_handle){
114 ALOGE("%s: camera obj not valid", __func__);
115 // simply free super frame
116 free(recvd_frame);
117 return;
118 }
119
120 QCameraChannel *pChannel = pme->m_channels[QCAMERA_CH_TYPE_CAPTURE];
121 if (pChannel == NULL ||
122 pChannel->getMyHandle() != recvd_frame->ch_id) {
123 ALOGE("%s: Capture channel doesn't exist, return here", __func__);
124 return;
125 }
126
127 // save a copy for the superbuf
128 mm_camera_super_buf_t* frame =
129 (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t));
130 if (frame == NULL) {
131 ALOGE("%s: Error allocating memory to save received_frame structure.", __func__);
132 pChannel->bufDone(recvd_frame);
133 return;
134 }
135 *frame = *recvd_frame;
136
137 // send to postprocessor
138 pme->m_postprocessor.processData(frame);
139
140 /* START of test register face image for face authentication */
141 #ifdef QCOM_TEST_FACE_REGISTER_FACE
142 static uint8_t bRunFaceReg = 1;
143
144 if (bRunFaceReg > 0) {
145 // find snapshot frame
146 QCameraStream *main_stream = NULL;
147 mm_camera_buf_def_t *main_frame = NULL;
148 for (int i = 0; i < recvd_frame->num_bufs; i++) {
149 QCameraStream *pStream =
150 pChannel->getStreamByHandle(recvd_frame->bufs[i]->stream_id);
151 if (pStream != NULL) {
152 if (pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT) ||
153 pStream->isTypeOf(CAM_STREAM_TYPE_NON_ZSL_SNAPSHOT)) {
154 main_stream = pStream;
155 main_frame = recvd_frame->bufs[i];
156 break;
157 }
158 }
159 }
160 if (main_stream != NULL && main_frame != NULL) {
161 int32_t faceId = -1;
162 cam_pp_offline_src_config_t config;
163 memset(&config, 0, sizeof(cam_pp_offline_src_config_t));
164 config.num_of_bufs = 1;
165 main_stream->getFormat(config.input_fmt);
166 main_stream->getFrameDimension(config.input_dim);
167 main_stream->getFrameOffset(config.input_buf_planes.plane_info);
168 ALOGD("DEBUG: registerFaceImage E");
169 int32_t rc = pme->registerFaceImage(main_frame->buffer, &config, faceId);
170 ALOGD("DEBUG: registerFaceImage X, ret=%d, faceId=%d", rc, faceId);
171 bRunFaceReg = 0;
172 }
173 }
174
175 #endif
176 /* END of test register face image for face authentication */
177
178 ALOGD("[KPI Perf] %s: X", __func__);
179 }
180
181 /*===========================================================================
182 * FUNCTION : postproc_channel_cb_routine
183 *
184 * DESCRIPTION: helper function to handle postprocess superbuf callback directly from
185 * mm-camera-interface
186 *
187 * PARAMETERS :
188 * @recvd_frame : received super buffer
189 * @userdata : user data ptr
190 *
191 * RETURN : None
192 *
193 * NOTE : recvd_frame will be released after this call by caller, so if
194 * async operation needed for recvd_frame, it's our responsibility
195 * to save a copy for this variable to be used later.
196 *==========================================================================*/
postproc_channel_cb_routine(mm_camera_super_buf_t * recvd_frame,void * userdata)197 void QCamera2HardwareInterface::postproc_channel_cb_routine(mm_camera_super_buf_t *recvd_frame,
198 void *userdata)
199 {
200 ALOGD("[KPI Perf] %s: E", __func__);
201 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata;
202 if (pme == NULL ||
203 pme->mCameraHandle == NULL ||
204 pme->mCameraHandle->camera_handle != recvd_frame->camera_handle){
205 ALOGE("%s: camera obj not valid", __func__);
206 // simply free super frame
207 free(recvd_frame);
208 return;
209 }
210
211 // save a copy for the superbuf
212 mm_camera_super_buf_t* frame =
213 (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t));
214 if (frame == NULL) {
215 ALOGE("%s: Error allocating memory to save received_frame structure.", __func__);
216 return;
217 }
218 *frame = *recvd_frame;
219
220 // send to postprocessor
221 pme->m_postprocessor.processPPData(frame);
222
223 ALOGD("[KPI Perf] %s: X", __func__);
224 }
225
226 /*===========================================================================
227 * FUNCTION : preview_stream_cb_routine
228 *
229 * DESCRIPTION: helper function to handle preview frame from preview stream in
230 * normal case with display.
231 *
232 * PARAMETERS :
233 * @super_frame : received super buffer
234 * @stream : stream object
235 * @userdata : user data ptr
236 *
237 * RETURN : None
238 *
239 * NOTE : caller passes the ownership of super_frame, it's our
240 * responsibility to free super_frame once it's done. The new
241 * preview frame will be sent to display, and an older frame
242 * will be dequeued from display and needs to be returned back
243 * to kernel for future use.
244 *==========================================================================*/
preview_stream_cb_routine(mm_camera_super_buf_t * super_frame,QCameraStream * stream,void * userdata)245 void QCamera2HardwareInterface::preview_stream_cb_routine(mm_camera_super_buf_t *super_frame,
246 QCameraStream * stream,
247 void *userdata)
248 {
249 ALOGD("[KPI Perf] %s : BEGIN", __func__);
250 int err = NO_ERROR;
251 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata;
252 QCameraGrallocMemory *memory = (QCameraGrallocMemory *)super_frame->bufs[0]->mem_info;
253
254 if (pme == NULL) {
255 ALOGE("%s: Invalid hardware object", __func__);
256 free(super_frame);
257 return;
258 }
259 if (memory == NULL) {
260 ALOGE("%s: Invalid memory object", __func__);
261 free(super_frame);
262 return;
263 }
264
265 mm_camera_buf_def_t *frame = super_frame->bufs[0];
266 if (NULL == frame) {
267 ALOGE("%s: preview frame is NLUL", __func__);
268 free(super_frame);
269 return;
270 }
271
272 if (!pme->needProcessPreviewFrame()) {
273 ALOGE("%s: preview is not running, no need to process", __func__);
274 stream->bufDone(frame->buf_idx);
275 free(super_frame);
276 return;
277 }
278
279 if (pme->needDebugFps()) {
280 pme->debugShowPreviewFPS();
281 }
282
283 int idx = frame->buf_idx;
284 pme->dumpFrameToFile(frame->buffer, frame->frame_len,
285 frame->frame_idx, QCAMERA_DUMP_FRM_PREVIEW);
286
287 // Display the buffer.
288 int dequeuedIdx = memory->displayBuffer(idx);
289 if (dequeuedIdx < 0 || dequeuedIdx >= memory->getCnt()) {
290 ALOGD("%s: Invalid dequeued buffer index %d from display",
291 __func__, dequeuedIdx);
292 } else {
293 // Return dequeued buffer back to driver
294 err = stream->bufDone(dequeuedIdx);
295 if ( err < 0) {
296 ALOGE("stream bufDone failed %d", err);
297 }
298 }
299
300 // Handle preview data callback
301 if (pme->mDataCb != NULL && pme->msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_FRAME) > 0) {
302 camera_memory_t *previewMem = NULL;
303 camera_memory_t *data = NULL;
304 int previewBufSize;
305 cam_dimension_t preview_dim;
306 cam_format_t previewFmt;
307 stream->getFrameDimension(preview_dim);
308 stream->getFormat(previewFmt);
309
310 /* The preview buffer size in the callback should be (width*height*bytes_per_pixel)
311 * As all preview formats we support, use 12 bits per pixel, buffer size = previewWidth * previewHeight * 3/2.
312 * We need to put a check if some other formats are supported in future. */
313 if ((previewFmt == CAM_FORMAT_YUV_420_NV21) ||
314 (previewFmt == CAM_FORMAT_YUV_420_NV12) ||
315 (previewFmt == CAM_FORMAT_YUV_420_YV12)) {
316 if(previewFmt == CAM_FORMAT_YUV_420_YV12) {
317 previewBufSize = ((preview_dim.width+15)/16) * 16 * preview_dim.height +
318 ((preview_dim.width/2+15)/16) * 16* preview_dim.height;
319 } else {
320 previewBufSize = preview_dim.width * preview_dim.height * 3/2;
321 }
322 if(previewBufSize != memory->getSize(idx)) {
323 previewMem = pme->mGetMemory(memory->getFd(idx),
324 previewBufSize, 1, pme->mCallbackCookie);
325 if (!previewMem || !previewMem->data) {
326 ALOGE("%s: mGetMemory failed.\n", __func__);
327 } else {
328 data = previewMem;
329 }
330 } else
331 data = memory->getMemory(idx, false);
332 } else {
333 data = memory->getMemory(idx, false);
334 ALOGE("%s: Invalid preview format, buffer size in preview callback may be wrong.", __func__);
335 }
336 qcamera_callback_argm_t cbArg;
337 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
338 cbArg.cb_type = QCAMERA_DATA_CALLBACK;
339 cbArg.msg_type = CAMERA_MSG_PREVIEW_FRAME;
340 cbArg.data = data;
341 if ( previewMem ) {
342 cbArg.user_data = previewMem;
343 cbArg.release_cb = releaseCameraMemory;
344 }
345 cbArg.cookie = pme;
346 pme->m_cbNotifier.notifyCallback(cbArg);
347 }
348
349 free(super_frame);
350 ALOGD("[KPI Perf] %s : END", __func__);
351 return;
352 }
353
354 /*===========================================================================
355 * FUNCTION : nodisplay_preview_stream_cb_routine
356 *
357 * DESCRIPTION: helper function to handle preview frame from preview stream in
358 * no-display case
359 *
360 * PARAMETERS :
361 * @super_frame : received super buffer
362 * @stream : stream object
363 * @userdata : user data ptr
364 *
365 * RETURN : None
366 *
367 * NOTE : caller passes the ownership of super_frame, it's our
368 * responsibility to free super_frame once it's done.
369 *==========================================================================*/
nodisplay_preview_stream_cb_routine(mm_camera_super_buf_t * super_frame,QCameraStream * stream,void * userdata)370 void QCamera2HardwareInterface::nodisplay_preview_stream_cb_routine(
371 mm_camera_super_buf_t *super_frame,
372 QCameraStream *stream,
373 void * userdata)
374 {
375 ALOGD("[KPI Perf] %s E",__func__);
376 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata;
377 if (pme == NULL ||
378 pme->mCameraHandle == NULL ||
379 pme->mCameraHandle->camera_handle != super_frame->camera_handle){
380 ALOGE("%s: camera obj not valid", __func__);
381 // simply free super frame
382 free(super_frame);
383 return;
384 }
385 mm_camera_buf_def_t *frame = super_frame->bufs[0];
386 if (NULL == frame) {
387 ALOGE("%s: preview frame is NLUL", __func__);
388 free(super_frame);
389 return;
390 }
391
392 if (!pme->needProcessPreviewFrame()) {
393 ALOGD("%s: preview is not running, no need to process", __func__);
394 stream->bufDone(frame->buf_idx);
395 free(super_frame);
396 return;
397 }
398
399 if (pme->needDebugFps()) {
400 pme->debugShowPreviewFPS();
401 }
402
403 QCameraMemory *previewMemObj = (QCameraMemory *)frame->mem_info;
404 camera_memory_t *preview_mem = NULL;
405 if (previewMemObj != NULL) {
406 preview_mem = previewMemObj->getMemory(frame->buf_idx, false);
407 }
408 if (NULL != previewMemObj && NULL != preview_mem) {
409 pme->dumpFrameToFile(frame->buffer, frame->frame_len,
410 frame->frame_idx, QCAMERA_DUMP_FRM_PREVIEW);
411
412 if (pme->needProcessPreviewFrame() &&
413 pme->mDataCb != NULL &&
414 pme->msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_FRAME) > 0 ) {
415 qcamera_callback_argm_t cbArg;
416 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
417 cbArg.cb_type = QCAMERA_DATA_CALLBACK;
418 cbArg.msg_type = CAMERA_MSG_PREVIEW_FRAME;
419 cbArg.data = preview_mem;
420 int user_data = frame->buf_idx;
421 cbArg.user_data = ( void * ) user_data;
422 cbArg.cookie = stream;
423 cbArg.release_cb = returnStreamBuffer;
424 pme->m_cbNotifier.notifyCallback(cbArg);
425 } else {
426 stream->bufDone(frame->buf_idx);
427 }
428 }
429 free(super_frame);
430 ALOGD("[KPI Perf] %s X",__func__);
431 }
432
433 /*===========================================================================
434 * FUNCTION : postview_stream_cb_routine
435 *
436 * DESCRIPTION: helper function to handle post frame from postview stream
437 *
438 * PARAMETERS :
439 * @super_frame : received super buffer
440 * @stream : stream object
441 * @userdata : user data ptr
442 *
443 * RETURN : None
444 *
445 * NOTE : caller passes the ownership of super_frame, it's our
446 * responsibility to free super_frame once it's done.
447 *==========================================================================*/
postview_stream_cb_routine(mm_camera_super_buf_t * super_frame,QCameraStream * stream,void * userdata)448 void QCamera2HardwareInterface::postview_stream_cb_routine(mm_camera_super_buf_t *super_frame,
449 QCameraStream *stream,
450 void *userdata)
451 {
452 int err = NO_ERROR;
453 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata;
454 QCameraGrallocMemory *memory = (QCameraGrallocMemory *)super_frame->bufs[0]->mem_info;
455
456 if (pme == NULL) {
457 ALOGE("%s: Invalid hardware object", __func__);
458 free(super_frame);
459 return;
460 }
461 if (memory == NULL) {
462 ALOGE("%s: Invalid memory object", __func__);
463 free(super_frame);
464 return;
465 }
466
467 ALOGD("[KPI Perf] %s : BEGIN", __func__);
468
469 mm_camera_buf_def_t *frame = super_frame->bufs[0];
470 if (NULL == frame) {
471 ALOGE("%s: preview frame is NLUL", __func__);
472 free(super_frame);
473 return;
474 }
475
476 QCameraMemory *memObj = (QCameraMemory *)frame->mem_info;
477 if (NULL != memObj) {
478 pme->dumpFrameToFile(frame->buffer, frame->frame_len,
479 frame->frame_idx, QCAMERA_DUMP_FRM_THUMBNAIL);
480 }
481
482 // Display the buffer.
483 int dequeuedIdx = memory->displayBuffer(frame->buf_idx);
484 if (dequeuedIdx < 0 || dequeuedIdx >= memory->getCnt()) {
485 ALOGD("%s: Invalid dequeued buffer index %d",
486 __func__, dequeuedIdx);
487 free(super_frame);
488 return;
489 }
490
491 // Return dequeued buffer back to driver
492 err = stream->bufDone(dequeuedIdx);
493 if ( err < 0) {
494 ALOGE("stream bufDone failed %d", err);
495 }
496
497 free(super_frame);
498 ALOGD("[KPI Perf] %s : END", __func__);
499 return;
500 }
501
502 /*===========================================================================
503 * FUNCTION : video_stream_cb_routine
504 *
505 * DESCRIPTION: helper function to handle video frame from video stream
506 *
507 * PARAMETERS :
508 * @super_frame : received super buffer
509 * @stream : stream object
510 * @userdata : user data ptr
511 *
512 * RETURN : None
513 *
514 * NOTE : caller passes the ownership of super_frame, it's our
515 * responsibility to free super_frame once it's done. video
516 * frame will be sent to video encoder. Once video encoder is
517 * done with the video frame, it will call another API
518 * (release_recording_frame) to return the frame back
519 *==========================================================================*/
video_stream_cb_routine(mm_camera_super_buf_t * super_frame,QCameraStream *,void * userdata)520 void QCamera2HardwareInterface::video_stream_cb_routine(mm_camera_super_buf_t *super_frame,
521 QCameraStream */*stream*/,
522 void *userdata)
523 {
524 ALOGD("[KPI Perf] %s : BEGIN", __func__);
525 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata;
526 if (pme == NULL ||
527 pme->mCameraHandle == NULL ||
528 pme->mCameraHandle->camera_handle != super_frame->camera_handle){
529 ALOGE("%s: camera obj not valid", __func__);
530 // simply free super frame
531 free(super_frame);
532 return;
533 }
534 mm_camera_buf_def_t *frame = super_frame->bufs[0];
535
536 if (pme->needDebugFps()) {
537 pme->debugShowVideoFPS();
538 }
539
540 ALOGE("%s: Stream(%d), Timestamp: %ld %ld",
541 __func__,
542 frame->stream_id,
543 frame->ts.tv_sec,
544 frame->ts.tv_nsec);
545
546 nsecs_t timeStamp = nsecs_t(frame->ts.tv_sec) * 1000000000LL + frame->ts.tv_nsec;
547 ALOGE("Send Video frame to services/encoder TimeStamp : %lld", timeStamp);
548 QCameraMemory *videoMemObj = (QCameraMemory *)frame->mem_info;
549 camera_memory_t *video_mem = NULL;
550 if (NULL != videoMemObj) {
551 video_mem = videoMemObj->getMemory(frame->buf_idx, (pme->mStoreMetaDataInFrame > 0)? true : false);
552 }
553 if (NULL != videoMemObj && NULL != video_mem) {
554 pme->dumpFrameToFile(frame->buffer, frame->frame_len,
555 frame->frame_idx, QCAMERA_DUMP_FRM_VIDEO);
556 if ((pme->mDataCbTimestamp != NULL) &&
557 pme->msgTypeEnabledWithLock(CAMERA_MSG_VIDEO_FRAME) > 0) {
558 qcamera_callback_argm_t cbArg;
559 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
560 cbArg.cb_type = QCAMERA_DATA_TIMESTAMP_CALLBACK;
561 cbArg.msg_type = CAMERA_MSG_VIDEO_FRAME;
562 cbArg.data = video_mem;
563 cbArg.timestamp = timeStamp;
564 pme->m_cbNotifier.notifyCallback(cbArg);
565 }
566 }
567 free(super_frame);
568 ALOGD("[KPI Perf] %s : END", __func__);
569 }
570
571 /*===========================================================================
572 * FUNCTION : snapshot_stream_cb_routine
573 *
574 * DESCRIPTION: helper function to handle snapshot frame from snapshot stream
575 *
576 * PARAMETERS :
577 * @super_frame : received super buffer
578 * @stream : stream object
579 * @userdata : user data ptr
580 *
581 * RETURN : None
582 *
583 * NOTE : caller passes the ownership of super_frame, it's our
584 * responsibility to free super_frame once it's done. For
585 * snapshot, it need to send to postprocessor for jpeg
586 * encoding, therefore the ownership of super_frame will be
587 * hand to postprocessor.
588 *==========================================================================*/
snapshot_stream_cb_routine(mm_camera_super_buf_t * super_frame,QCameraStream *,void * userdata)589 void QCamera2HardwareInterface::snapshot_stream_cb_routine(mm_camera_super_buf_t *super_frame,
590 QCameraStream * /*stream*/,
591 void *userdata)
592 {
593 ALOGD("[KPI Perf] %s: E", __func__);
594 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata;
595 if (pme == NULL ||
596 pme->mCameraHandle == NULL ||
597 pme->mCameraHandle->camera_handle != super_frame->camera_handle){
598 ALOGE("%s: camera obj not valid", __func__);
599 // simply free super frame
600 free(super_frame);
601 return;
602 }
603
604 pme->m_postprocessor.processData(super_frame);
605
606 ALOGD("[KPI Perf] %s: X", __func__);
607 }
608
609 /*===========================================================================
610 * FUNCTION : raw_stream_cb_routine
611 *
612 * DESCRIPTION: helper function to handle raw dump frame from raw stream
613 *
614 * PARAMETERS :
615 * @super_frame : received super buffer
616 * @stream : stream object
617 * @userdata : user data ptr
618 *
619 * RETURN : None
620 *
621 * NOTE : caller passes the ownership of super_frame, it's our
622 * responsibility to free super_frame once it's done. For raw
623 * frame, there is no need to send to postprocessor for jpeg
624 * encoding. this function will play shutter and send the data
625 * callback to upper layer. Raw frame buffer will be returned
626 * back to kernel, and frame will be free after use.
627 *==========================================================================*/
raw_stream_cb_routine(mm_camera_super_buf_t * super_frame,QCameraStream *,void * userdata)628 void QCamera2HardwareInterface::raw_stream_cb_routine(mm_camera_super_buf_t * super_frame,
629 QCameraStream * /*stream*/,
630 void * userdata)
631 {
632 ALOGD("[KPI Perf] %s : BEGIN", __func__);
633 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata;
634 if (pme == NULL ||
635 pme->mCameraHandle == NULL ||
636 pme->mCameraHandle->camera_handle != super_frame->camera_handle){
637 ALOGE("%s: camera obj not valid", __func__);
638 // simply free super frame
639 free(super_frame);
640 return;
641 }
642
643 pme->m_postprocessor.processRawData(super_frame);
644 ALOGD("[KPI Perf] %s : END", __func__);
645 }
646
647 /*===========================================================================
648 * FUNCTION : metadata_stream_cb_routine
649 *
650 * DESCRIPTION: helper function to handle metadata frame from metadata stream
651 *
652 * PARAMETERS :
653 * @super_frame : received super buffer
654 * @stream : stream object
655 * @userdata : user data ptr
656 *
657 * RETURN : None
658 *
659 * NOTE : caller passes the ownership of super_frame, it's our
660 * responsibility to free super_frame once it's done. Metadata
661 * could have valid entries for face detection result or
662 * histogram statistics information.
663 *==========================================================================*/
metadata_stream_cb_routine(mm_camera_super_buf_t * super_frame,QCameraStream * stream,void * userdata)664 void QCamera2HardwareInterface::metadata_stream_cb_routine(mm_camera_super_buf_t * super_frame,
665 QCameraStream * stream,
666 void * userdata)
667 {
668 ALOGV("[KPI Perf] %s : BEGIN", __func__);
669 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata;
670 if (pme == NULL ||
671 pme->mCameraHandle == NULL ||
672 pme->mCameraHandle->camera_handle != super_frame->camera_handle){
673 ALOGE("%s: camera obj not valid", __func__);
674 // simply free super frame
675 free(super_frame);
676 return;
677 }
678
679 mm_camera_buf_def_t *frame = super_frame->bufs[0];
680 cam_metadata_info_t *pMetaData = (cam_metadata_info_t *)frame->buffer;
681
682 if (pMetaData->is_faces_valid) {
683 if (pMetaData->faces_data.num_faces_detected > MAX_ROI) {
684 ALOGE("%s: Invalid number of faces %d",
685 __func__, pMetaData->faces_data.num_faces_detected);
686 } else {
687 // process face detection result
688 ALOGD("[KPI Perf] %s: Number of faces detected %d",__func__,pMetaData->faces_data.num_faces_detected);
689 pme->processFaceDetectionResult(&pMetaData->faces_data);
690 }
691 }
692
693 if (pMetaData->is_stats_valid) {
694 // process histogram statistics info
695 pme->processHistogramStats(pMetaData->stats_data);
696 }
697
698 if (pMetaData->is_focus_valid) {
699 // process focus info
700 qcamera_sm_internal_evt_payload_t *payload =
701 (qcamera_sm_internal_evt_payload_t *)malloc(sizeof(qcamera_sm_internal_evt_payload_t));
702 if (NULL != payload) {
703 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
704 payload->evt_type = QCAMERA_INTERNAL_EVT_FOCUS_UPDATE;
705 payload->focus_data = pMetaData->focus_data;
706 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
707 if (rc != NO_ERROR) {
708 ALOGE("%s: processEVt failed", __func__);
709 free(payload);
710 payload = NULL;
711
712 }
713 } else {
714 ALOGE("%s: No memory for qcamera_sm_internal_evt_payload_t", __func__);
715 }
716 }
717
718 if (pMetaData->is_crop_valid) {
719 if (pMetaData->crop_data.num_of_streams > MAX_NUM_STREAMS) {
720 ALOGE("%s: Invalid num_of_streams %d in crop_data", __func__,
721 pMetaData->crop_data.num_of_streams);
722 } else {
723 pme->processZoomEvent(pMetaData->crop_data);
724 }
725 }
726
727 if (pMetaData->is_prep_snapshot_done_valid) {
728 qcamera_sm_internal_evt_payload_t *payload =
729 (qcamera_sm_internal_evt_payload_t *)malloc(sizeof(qcamera_sm_internal_evt_payload_t));
730 if (NULL != payload) {
731 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
732 payload->evt_type = QCAMERA_INTERNAL_EVT_PREP_SNAPSHOT_DONE;
733 payload->prep_snapshot_state = pMetaData->prep_snapshot_done_state;
734 int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
735 if (rc != NO_ERROR) {
736 ALOGE("%s: processEVt failed", __func__);
737 free(payload);
738 payload = NULL;
739
740 }
741 } else {
742 ALOGE("%s: No memory for qcamera_sm_internal_evt_payload_t", __func__);
743 }
744 }
745
746 stream->bufDone(frame->buf_idx);
747 free(super_frame);
748
749 ALOGV("[KPI Perf] %s : END", __func__);
750 }
751
752 /*===========================================================================
753 * FUNCTION : reprocess_stream_cb_routine
754 *
755 * DESCRIPTION: helper function to handle reprocess frame from reprocess stream
756 (after reprocess, e.g., ZSL snapshot frame after WNR if
757 * WNR is enabled)
758 *
759 * PARAMETERS :
760 * @super_frame : received super buffer
761 * @stream : stream object
762 * @userdata : user data ptr
763 *
764 * RETURN : None
765 *
766 * NOTE : caller passes the ownership of super_frame, it's our
767 * responsibility to free super_frame once it's done. In this
768 * case, reprocessed frame need to be passed to postprocessor
769 * for jpeg encoding.
770 *==========================================================================*/
reprocess_stream_cb_routine(mm_camera_super_buf_t * super_frame,QCameraStream *,void * userdata)771 void QCamera2HardwareInterface::reprocess_stream_cb_routine(mm_camera_super_buf_t * super_frame,
772 QCameraStream * /*stream*/,
773 void * userdata)
774 {
775 ALOGD("[KPI Perf] %s: E", __func__);
776 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata;
777 if (pme == NULL ||
778 pme->mCameraHandle == NULL ||
779 pme->mCameraHandle->camera_handle != super_frame->camera_handle){
780 ALOGE("%s: camera obj not valid", __func__);
781 // simply free super frame
782 free(super_frame);
783 return;
784 }
785
786 pme->m_postprocessor.processPPData(super_frame);
787
788 ALOGD("[KPI Perf] %s: X", __func__);
789 }
790
791 /*===========================================================================
792 * FUNCTION : dumpFrameToFile
793 *
794 * DESCRIPTION: helper function to dump frame into file for debug purpose.
795 *
796 * PARAMETERS :
797 * @data : data ptr
798 * @size : length of data buffer
799 * @index : identifier for data
800 * @dump_type : type of the frame to be dumped. Only such
801 * dump type is enabled, the frame will be
802 * dumped into a file.
803 *
804 * RETURN : None
805 *==========================================================================*/
dumpFrameToFile(const void * data,uint32_t size,int index,int dump_type)806 void QCamera2HardwareInterface::dumpFrameToFile(const void *data,
807 uint32_t size,
808 int index,
809 int dump_type)
810 {
811 char value[PROPERTY_VALUE_MAX];
812 property_get("persist.camera.dumpimg", value, "0");
813 int32_t enabled = atoi(value);
814 int frm_num = 0;
815 uint32_t skip_mode = 0;
816
817 char buf[32];
818 cam_dimension_t dim;
819 memset(buf, 0, sizeof(buf));
820 memset(&dim, 0, sizeof(dim));
821
822 if(enabled & QCAMERA_DUMP_FRM_MASK_ALL) {
823 if((enabled & dump_type) && data) {
824 frm_num = ((enabled & 0xffff0000) >> 16);
825 if(frm_num == 0) {
826 frm_num = 10; //default 10 frames
827 }
828 if(frm_num > 256) {
829 frm_num = 256; //256 buffers cycle around
830 }
831 skip_mode = ((enabled & 0x0000ff00) >> 8);
832 if(skip_mode == 0) {
833 skip_mode = 1; //no-skip
834 }
835
836 if( mDumpSkipCnt % skip_mode == 0) {
837 if((frm_num == 256) && (mDumpFrmCnt >= frm_num)) {
838 // reset frame count if cycling
839 mDumpFrmCnt = 0;
840 }
841 if (mDumpFrmCnt >= 0 && mDumpFrmCnt <= frm_num) {
842 switch (dump_type) {
843 case QCAMERA_DUMP_FRM_PREVIEW:
844 {
845 mParameters.getStreamDimension(CAM_STREAM_TYPE_PREVIEW, dim);
846 snprintf(buf, sizeof(buf), "/data/%dp_%dx%d_%d.yuv",
847 mDumpFrmCnt, dim.width, dim.height, index);
848 }
849 break;
850 case QCAMERA_DUMP_FRM_THUMBNAIL:
851 {
852 mParameters.getStreamDimension(CAM_STREAM_TYPE_POSTVIEW, dim);
853 snprintf(buf, sizeof(buf), "/data/%dt_%dx%d_%d.yuv",
854 mDumpFrmCnt, dim.width, dim.height, index);
855 }
856 break;
857 case QCAMERA_DUMP_FRM_SNAPSHOT:
858 {
859 if (mParameters.isZSLMode())
860 mParameters.getStreamDimension(CAM_STREAM_TYPE_SNAPSHOT, dim);
861 else
862 mParameters.getStreamDimension(CAM_STREAM_TYPE_NON_ZSL_SNAPSHOT, dim);
863 snprintf(buf, sizeof(buf), "/data/%ds_%dx%d_%d.yuv",
864 mDumpFrmCnt, dim.width, dim.height, index);
865 }
866 break;
867 case QCAMERA_DUMP_FRM_VIDEO:
868 {
869 mParameters.getStreamDimension(CAM_STREAM_TYPE_VIDEO, dim);
870 snprintf(buf, sizeof(buf), "/data/%dv_%dx%d_%d.yuv",
871 mDumpFrmCnt, dim.width, dim.height, index);
872 }
873 break;
874 case QCAMERA_DUMP_FRM_RAW:
875 {
876 mParameters.getStreamDimension(CAM_STREAM_TYPE_RAW, dim);
877 snprintf(buf, sizeof(buf), "/data/%dr_%dx%d_%d.yuv",
878 mDumpFrmCnt, dim.width, dim.height, index);
879 }
880 break;
881 case QCAMERA_DUMP_FRM_JPEG:
882 {
883 if (mParameters.isZSLMode())
884 mParameters.getStreamDimension(CAM_STREAM_TYPE_SNAPSHOT, dim);
885 else
886 mParameters.getStreamDimension(CAM_STREAM_TYPE_NON_ZSL_SNAPSHOT, dim);
887 snprintf(buf, sizeof(buf), "/data/%dj_%dx%d_%d.yuv",
888 mDumpFrmCnt, dim.width, dim.height, index);
889 }
890 break;
891 default:
892 ALOGE("%s: Not supported for dumping stream type %d",
893 __func__, dump_type);
894 return;
895 }
896
897 ALOGD("dump %s size =%d, data = %p", buf, size, data);
898 int file_fd = open(buf, O_RDWR | O_CREAT, 0777);
899 if (file_fd > 0) {
900 int written_len = write(file_fd, data, size);
901 ALOGD("%s: written number of bytes %d\n", __func__, written_len);
902 close(file_fd);
903 } else {
904 ALOGE("%s: fail t open file for image dumping", __func__);
905 }
906 mDumpFrmCnt++;
907 }
908 }
909 mDumpSkipCnt++;
910 }
911 } else {
912 mDumpFrmCnt = 0;
913 }
914 }
915
916 /*===========================================================================
917 * FUNCTION : debugShowVideoFPS
918 *
919 * DESCRIPTION: helper function to log video frame FPS for debug purpose.
920 *
921 * PARAMETERS : None
922 *
923 * RETURN : None
924 *==========================================================================*/
debugShowVideoFPS()925 void QCamera2HardwareInterface::debugShowVideoFPS()
926 {
927 static int n_vFrameCount = 0;
928 static int n_vLastFrameCount = 0;
929 static nsecs_t n_vLastFpsTime = 0;
930 static float n_vFps = 0;
931 n_vFrameCount++;
932 nsecs_t now = systemTime();
933 nsecs_t diff = now - n_vLastFpsTime;
934 if (diff > ms2ns(250)) {
935 n_vFps = ((n_vFrameCount - n_vLastFrameCount) * float(s2ns(1))) / diff;
936 ALOGE("Video Frames Per Second: %.4f", n_vFps);
937 n_vLastFpsTime = now;
938 n_vLastFrameCount = n_vFrameCount;
939 }
940 }
941
942 /*===========================================================================
943 * FUNCTION : debugShowPreviewFPS
944 *
945 * DESCRIPTION: helper function to log preview frame FPS for debug purpose.
946 *
947 * PARAMETERS : None
948 *
949 * RETURN : None
950 *==========================================================================*/
debugShowPreviewFPS()951 void QCamera2HardwareInterface::debugShowPreviewFPS()
952 {
953 static int n_pFrameCount = 0;
954 static int n_pLastFrameCount = 0;
955 static nsecs_t n_pLastFpsTime = 0;
956 static float n_pFps = 0;
957 n_pFrameCount++;
958 nsecs_t now = systemTime();
959 nsecs_t diff = now - n_pLastFpsTime;
960 if (diff > ms2ns(250)) {
961 n_pFps = ((n_pFrameCount - n_pLastFrameCount) * float(s2ns(1))) / diff;
962 ALOGE("Preview Frames Per Second: %.4f", n_pFps);
963 n_pLastFpsTime = now;
964 n_pLastFrameCount = n_pFrameCount;
965 }
966 }
967
968 /*===========================================================================
969 * FUNCTION : ~QCameraCbNotifier
970 *
971 * DESCRIPTION: Destructor for exiting the callback context.
972 *
973 * PARAMETERS : None
974 *
975 * RETURN : None
976 *==========================================================================*/
~QCameraCbNotifier()977 QCameraCbNotifier::~QCameraCbNotifier()
978 {
979 mProcTh.exit();
980 }
981
982 /*===========================================================================
983 * FUNCTION : releaseNotifications
984 *
985 * DESCRIPTION: callback for releasing data stored in the callback queue.
986 *
987 * PARAMETERS :
988 * @data : data to be released
989 * @user_data : context data
990 *
991 * RETURN : None
992 *==========================================================================*/
releaseNotifications(void * data,void * user_data)993 void QCameraCbNotifier::releaseNotifications(void *data, void *user_data)
994 {
995 qcamera_callback_argm_t *arg = ( qcamera_callback_argm_t * ) data;
996
997 if ( ( NULL != arg ) && ( NULL != user_data ) ) {
998 if ( arg->release_cb ) {
999 arg->release_cb(arg->user_data, arg->cookie);
1000 }
1001 }
1002 }
1003
1004 /*===========================================================================
1005 * FUNCTION : matchSnapshotNotifications
1006 *
1007 * DESCRIPTION: matches snapshot data callbacks
1008 *
1009 * PARAMETERS :
1010 * @data : data to match
1011 * @user_data : context data
1012 *
1013 * RETURN : bool match
1014 * true - match found
1015 * false- match not found
1016 *==========================================================================*/
matchSnapshotNotifications(void * data,void *)1017 bool QCameraCbNotifier::matchSnapshotNotifications(void *data,
1018 void */*user_data*/)
1019 {
1020 qcamera_callback_argm_t *arg = ( qcamera_callback_argm_t * ) data;
1021 if ( NULL != arg ) {
1022 if ( QCAMERA_DATA_SNAPSHOT_CALLBACK == arg->cb_type ) {
1023 return true;
1024 }
1025 }
1026
1027 return false;
1028 }
1029
1030 /*===========================================================================
1031 * FUNCTION : cbNotifyRoutine
1032 *
1033 * DESCRIPTION: callback thread which interfaces with the upper layers
1034 * given input commands.
1035 *
1036 * PARAMETERS :
1037 * @data : context data
1038 *
1039 * RETURN : None
1040 *==========================================================================*/
cbNotifyRoutine(void * data)1041 void * QCameraCbNotifier::cbNotifyRoutine(void * data)
1042 {
1043 int running = 1;
1044 int ret;
1045 QCameraCbNotifier *pme = (QCameraCbNotifier *)data;
1046 QCameraCmdThread *cmdThread = &pme->mProcTh;
1047 uint8_t isSnapshotActive = FALSE;
1048 uint32_t numOfSnapshotExpected = 0;
1049 uint32_t numOfSnapshotRcvd = 0;
1050
1051 ALOGV("%s: E", __func__);
1052 do {
1053 do {
1054 ret = cam_sem_wait(&cmdThread->cmd_sem);
1055 if (ret != 0 && errno != EINVAL) {
1056 ALOGV("%s: cam_sem_wait error (%s)",
1057 __func__, strerror(errno));
1058 return NULL;
1059 }
1060 } while (ret != 0);
1061
1062 camera_cmd_type_t cmd = cmdThread->getCmd();
1063 ALOGV("%s: get cmd %d", __func__, cmd);
1064 switch (cmd) {
1065 case CAMERA_CMD_TYPE_START_DATA_PROC:
1066 {
1067 isSnapshotActive = TRUE;
1068 numOfSnapshotExpected = pme->mParent->numOfSnapshotsExpected();
1069 numOfSnapshotRcvd = 0;
1070 }
1071 break;
1072 case CAMERA_CMD_TYPE_STOP_DATA_PROC:
1073 {
1074 pme->mDataQ.flushNodes(matchSnapshotNotifications);
1075 isSnapshotActive = FALSE;
1076
1077 numOfSnapshotExpected = 0;
1078 numOfSnapshotRcvd = 0;
1079 }
1080 break;
1081 case CAMERA_CMD_TYPE_DO_NEXT_JOB:
1082 {
1083 qcamera_callback_argm_t *cb =
1084 (qcamera_callback_argm_t *)pme->mDataQ.dequeue();
1085 if (NULL != cb) {
1086 ALOGV("%s: cb type %d received",
1087 __func__,
1088 cb->cb_type);
1089
1090 if (pme->mParent->msgTypeEnabledWithLock(cb->msg_type)) {
1091 switch (cb->cb_type) {
1092 case QCAMERA_NOTIFY_CALLBACK:
1093 {
1094 if (cb->msg_type == CAMERA_MSG_FOCUS) {
1095 ALOGD("[KPI Perf] %s : sending focus evt to app", __func__);
1096 }
1097 if (pme->mNotifyCb) {
1098 pme->mNotifyCb(cb->msg_type,
1099 cb->ext1,
1100 cb->ext2,
1101 pme->mCallbackCookie);
1102 } else {
1103 ALOGE("%s : notify callback not set!",
1104 __func__);
1105 }
1106 }
1107 break;
1108 case QCAMERA_DATA_CALLBACK:
1109 {
1110 if (pme->mDataCb) {
1111 pme->mDataCb(cb->msg_type,
1112 cb->data,
1113 cb->index,
1114 cb->metadata,
1115 pme->mCallbackCookie);
1116 } else {
1117 ALOGE("%s : data callback not set!",
1118 __func__);
1119 }
1120 }
1121 break;
1122 case QCAMERA_DATA_TIMESTAMP_CALLBACK:
1123 {
1124 if(pme->mDataCbTimestamp) {
1125 pme->mDataCbTimestamp(cb->timestamp,
1126 cb->msg_type,
1127 cb->data,
1128 cb->index,
1129 pme->mCallbackCookie);
1130 } else {
1131 ALOGE("%s:data cb with tmp not set!",
1132 __func__);
1133 }
1134 }
1135 break;
1136 case QCAMERA_DATA_SNAPSHOT_CALLBACK:
1137 {
1138 if (TRUE == isSnapshotActive && pme->mDataCb ) {
1139 numOfSnapshotRcvd++;
1140 if (numOfSnapshotExpected > 0 &&
1141 numOfSnapshotExpected == numOfSnapshotRcvd) {
1142 // notify HWI that snapshot is done
1143 pme->mParent->processSyncEvt(QCAMERA_SM_EVT_SNAPSHOT_DONE,
1144 NULL);
1145 }
1146 pme->mDataCb(cb->msg_type,
1147 cb->data,
1148 cb->index,
1149 cb->metadata,
1150 pme->mCallbackCookie);
1151 }
1152 }
1153 break;
1154 default:
1155 {
1156 ALOGE("%s : invalid cb type %d",
1157 __func__,
1158 cb->cb_type);
1159 }
1160 break;
1161 };
1162 } else {
1163 ALOGE("%s : cb message type %d not enabled!",
1164 __func__,
1165 cb->msg_type);
1166 }
1167 if ( cb->release_cb ) {
1168 cb->release_cb(cb->user_data, cb->cookie);
1169 }
1170 delete cb;
1171 } else {
1172 ALOGE("%s: invalid cb type passed", __func__);
1173 }
1174 }
1175 break;
1176 case CAMERA_CMD_TYPE_EXIT:
1177 {
1178 pme->mDataQ.flush();
1179 running = 0;
1180 }
1181 break;
1182 default:
1183 break;
1184 }
1185 } while (running);
1186 ALOGV("%s: X", __func__);
1187
1188 return NULL;
1189 }
1190
1191 /*===========================================================================
1192 * FUNCTION : notifyCallback
1193 *
1194 * DESCRIPTION: Enqueus pending callback notifications for the upper layers.
1195 *
1196 * PARAMETERS :
1197 * @cbArgs : callback arguments
1198 *
1199 * RETURN : int32_t type of status
1200 * NO_ERROR -- success
1201 * none-zero failure code
1202 *==========================================================================*/
notifyCallback(qcamera_callback_argm_t & cbArgs)1203 int32_t QCameraCbNotifier::notifyCallback(qcamera_callback_argm_t &cbArgs)
1204 {
1205 qcamera_callback_argm_t *cbArg = new qcamera_callback_argm_t();
1206 if (NULL == cbArg) {
1207 ALOGE("%s: no mem for qcamera_callback_argm_t", __func__);
1208 return NO_MEMORY;
1209 }
1210 memset(cbArg, 0, sizeof(qcamera_callback_argm_t));
1211 *cbArg = cbArgs;
1212
1213 if (mDataQ.enqueue((void *)cbArg)) {
1214 mProcTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE);
1215 } else {
1216 ALOGE("%s: Error adding cb data into queue", __func__);
1217 delete cbArg;
1218 return UNKNOWN_ERROR;
1219 }
1220
1221 return NO_ERROR;
1222 }
1223
1224 /*===========================================================================
1225 * FUNCTION : setCallbacks
1226 *
1227 * DESCRIPTION: Initializes the callback functions, which would be used for
1228 * communication with the upper layers and launches the callback
1229 * context in which the callbacks will occur.
1230 *
1231 * PARAMETERS :
1232 * @notifyCb : notification callback
1233 * @dataCb : data callback
1234 * @dataCbTimestamp : data with timestamp callback
1235 * @callbackCookie : callback context data
1236 *
1237 * RETURN : None
1238 *==========================================================================*/
setCallbacks(camera_notify_callback notifyCb,camera_data_callback dataCb,camera_data_timestamp_callback dataCbTimestamp,void * callbackCookie)1239 void QCameraCbNotifier::setCallbacks(camera_notify_callback notifyCb,
1240 camera_data_callback dataCb,
1241 camera_data_timestamp_callback dataCbTimestamp,
1242 void *callbackCookie)
1243 {
1244 if ( ( NULL == mNotifyCb ) &&
1245 ( NULL == mDataCb ) &&
1246 ( NULL == mDataCbTimestamp ) &&
1247 ( NULL == mCallbackCookie ) ) {
1248 mNotifyCb = notifyCb;
1249 mDataCb = dataCb;
1250 mDataCbTimestamp = dataCbTimestamp;
1251 mCallbackCookie = callbackCookie;
1252 mProcTh.launch(cbNotifyRoutine, this);
1253 } else {
1254 ALOGE("%s : Camera callback notifier already initialized!",
1255 __func__);
1256 }
1257 }
1258
1259 /*===========================================================================
1260 * FUNCTION : startSnapshots
1261 *
1262 * DESCRIPTION: Enables snapshot mode
1263 *
1264 * PARAMETERS : None
1265 *
1266 * RETURN : int32_t type of status
1267 * NO_ERROR -- success
1268 * none-zero failure code
1269 *==========================================================================*/
startSnapshots()1270 int32_t QCameraCbNotifier::startSnapshots()
1271 {
1272 return mProcTh.sendCmd(CAMERA_CMD_TYPE_START_DATA_PROC, FALSE, TRUE);
1273 }
1274
1275 /*===========================================================================
1276 * FUNCTION : stopSnapshots
1277 *
1278 * DESCRIPTION: Disables snapshot processing mode
1279 *
1280 * PARAMETERS : None
1281 *
1282 * RETURN : None
1283 *==========================================================================*/
stopSnapshots()1284 void QCameraCbNotifier::stopSnapshots()
1285 {
1286 mProcTh.sendCmd(CAMERA_CMD_TYPE_STOP_DATA_PROC, FALSE, TRUE);
1287 }
1288
1289 }; // namespace qcamera
1290