QCamera2HWI.cpp revision 744f5403bebb0e27140d16a5df7a341713c24a13
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 <cutils/properties.h>
33#include <hardware/camera.h>
34#include <stdlib.h>
35#include <utils/Errors.h>
36#include <gralloc_priv.h>
37
38#include "QCamera2HWI.h"
39#include "QCameraMem.h"
40
41#define MAP_TO_DRIVER_COORDINATE(val, base, scale, offset) (val * scale / base + offset)
42#define CAMERA_MIN_STREAMING_BUFFERS     3
43#define CAMERA_MIN_JPEG_ENCODING_BUFFERS 2
44#define CAMERA_MIN_VIDEO_BUFFERS         9
45
46namespace qcamera {
47
48cam_capability_t *gCamCapability[MM_CAMERA_MAX_NUM_SENSORS];
49static pthread_mutex_t g_camlock = PTHREAD_MUTEX_INITIALIZER;
50
51camera_device_ops_t QCamera2HardwareInterface::mCameraOps = {
52    set_preview_window:         QCamera2HardwareInterface::set_preview_window,
53    set_callbacks:              QCamera2HardwareInterface::set_CallBacks,
54    enable_msg_type:            QCamera2HardwareInterface::enable_msg_type,
55    disable_msg_type:           QCamera2HardwareInterface::disable_msg_type,
56    msg_type_enabled:           QCamera2HardwareInterface::msg_type_enabled,
57
58    start_preview:              QCamera2HardwareInterface::start_preview,
59    stop_preview:               QCamera2HardwareInterface::stop_preview,
60    preview_enabled:            QCamera2HardwareInterface::preview_enabled,
61    store_meta_data_in_buffers: QCamera2HardwareInterface::store_meta_data_in_buffers,
62
63    start_recording:            QCamera2HardwareInterface::start_recording,
64    stop_recording:             QCamera2HardwareInterface::stop_recording,
65    recording_enabled:          QCamera2HardwareInterface::recording_enabled,
66    release_recording_frame:    QCamera2HardwareInterface::release_recording_frame,
67
68    auto_focus:                 QCamera2HardwareInterface::auto_focus,
69    cancel_auto_focus:          QCamera2HardwareInterface::cancel_auto_focus,
70
71    take_picture:               QCamera2HardwareInterface::take_picture,
72    cancel_picture:             QCamera2HardwareInterface::cancel_picture,
73
74    set_parameters:             QCamera2HardwareInterface::set_parameters,
75    get_parameters:             QCamera2HardwareInterface::get_parameters,
76    put_parameters:             QCamera2HardwareInterface::put_parameters,
77    send_command:               QCamera2HardwareInterface::send_command,
78
79    release:                    QCamera2HardwareInterface::release,
80    dump:                       QCamera2HardwareInterface::dump,
81};
82
83/*===========================================================================
84 * FUNCTION   : set_preview_window
85 *
86 * DESCRIPTION: set preview window.
87 *
88 * PARAMETERS :
89 *   @device  : ptr to camera device struct
90 *   @window  : window ops table
91 *
92 * RETURN     : int32_t type of status
93 *              NO_ERROR  -- success
94 *              none-zero failure code
95 *==========================================================================*/
96int QCamera2HardwareInterface::set_preview_window(struct camera_device *device,
97        struct preview_stream_ops *window)
98{
99    int rc = NO_ERROR;
100    QCamera2HardwareInterface *hw =
101        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
102    if (!hw) {
103        ALOGE("%s: NULL camera device", __func__);
104        return BAD_VALUE;
105    }
106
107    hw->lockAPI();
108    rc = hw->processAPI(QCAMERA_SM_EVT_SET_PREVIEW_WINDOW, (void *)window);
109    if (rc == NO_ERROR) {
110        hw->waitAPIResult(QCAMERA_SM_EVT_SET_PREVIEW_WINDOW);
111        rc = hw->m_apiResult.status;
112    }
113    hw->unlockAPI();
114
115    return rc;
116}
117
118/*===========================================================================
119 * FUNCTION   : set_CallBacks
120 *
121 * DESCRIPTION: set callbacks for notify and data
122 *
123 * PARAMETERS :
124 *   @device     : ptr to camera device struct
125 *   @notify_cb  : notify cb
126 *   @data_cb    : data cb
127 *   @data_cb_timestamp  : video data cd with timestamp
128 *   @get_memory : ops table for request gralloc memory
129 *   @user       : user data ptr
130 *
131 * RETURN     : none
132 *==========================================================================*/
133void QCamera2HardwareInterface::set_CallBacks(struct camera_device *device,
134        camera_notify_callback notify_cb,
135        camera_data_callback data_cb,
136        camera_data_timestamp_callback data_cb_timestamp,
137        camera_request_memory get_memory,
138        void *user)
139{
140    QCamera2HardwareInterface *hw =
141        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
142    if (!hw) {
143        ALOGE("NULL camera device");
144        return;
145    }
146
147    qcamera_sm_evt_setcb_payload_t payload;
148    payload.notify_cb = notify_cb;
149    payload.data_cb = data_cb;
150    payload.data_cb_timestamp = data_cb_timestamp;
151    payload.get_memory = get_memory;
152    payload.user = user;
153
154    hw->lockAPI();
155    int32_t rc = hw->processAPI(QCAMERA_SM_EVT_SET_CALLBACKS, (void *)&payload);
156    if (rc == NO_ERROR) {
157        hw->waitAPIResult(QCAMERA_SM_EVT_SET_CALLBACKS);
158    }
159    hw->unlockAPI();
160}
161
162/*===========================================================================
163 * FUNCTION   : enable_msg_type
164 *
165 * DESCRIPTION: enable certain msg type
166 *
167 * PARAMETERS :
168 *   @device     : ptr to camera device struct
169 *   @msg_type   : msg type mask
170 *
171 * RETURN     : none
172 *==========================================================================*/
173void QCamera2HardwareInterface::enable_msg_type(struct camera_device *device, int32_t msg_type)
174{
175    QCamera2HardwareInterface *hw =
176        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
177    if (!hw) {
178        ALOGE("NULL camera device");
179        return;
180    }
181    hw->lockAPI();
182    int32_t rc = hw->processAPI(QCAMERA_SM_EVT_ENABLE_MSG_TYPE, (void *)msg_type);
183    if (rc == NO_ERROR) {
184        hw->waitAPIResult(QCAMERA_SM_EVT_ENABLE_MSG_TYPE);
185    }
186    hw->unlockAPI();
187}
188
189/*===========================================================================
190 * FUNCTION   : disable_msg_type
191 *
192 * DESCRIPTION: disable certain msg type
193 *
194 * PARAMETERS :
195 *   @device     : ptr to camera device struct
196 *   @msg_type   : msg type mask
197 *
198 * RETURN     : none
199 *==========================================================================*/
200void QCamera2HardwareInterface::disable_msg_type(struct camera_device *device, int32_t msg_type)
201{
202    QCamera2HardwareInterface *hw =
203        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
204    if (!hw) {
205        ALOGE("NULL camera device");
206        return;
207    }
208    hw->lockAPI();
209    int32_t rc = hw->processAPI(QCAMERA_SM_EVT_DISABLE_MSG_TYPE, (void *)msg_type);
210    if (rc == NO_ERROR) {
211        hw->waitAPIResult(QCAMERA_SM_EVT_DISABLE_MSG_TYPE);
212    }
213    hw->unlockAPI();
214}
215
216/*===========================================================================
217 * FUNCTION   : msg_type_enabled
218 *
219 * DESCRIPTION: if certain msg type is enabled
220 *
221 * PARAMETERS :
222 *   @device     : ptr to camera device struct
223 *   @msg_type   : msg type mask
224 *
225 * RETURN     : 1 -- enabled
226 *              0 -- not enabled
227 *==========================================================================*/
228int QCamera2HardwareInterface::msg_type_enabled(struct camera_device *device, int32_t msg_type)
229{
230    int ret = NO_ERROR;
231    QCamera2HardwareInterface *hw =
232        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
233    if (!hw) {
234        ALOGE("NULL camera device");
235        return BAD_VALUE;
236    }
237    hw->lockAPI();
238    ret = hw->processAPI(QCAMERA_SM_EVT_MSG_TYPE_ENABLED, (void *)msg_type);
239    if (ret == NO_ERROR) {
240        hw->waitAPIResult(QCAMERA_SM_EVT_MSG_TYPE_ENABLED);
241        ret = hw->m_apiResult.enabled;
242    }
243    hw->unlockAPI();
244
245   return ret;
246}
247
248/*===========================================================================
249 * FUNCTION   : start_preview
250 *
251 * DESCRIPTION: start preview
252 *
253 * PARAMETERS :
254 *   @device  : ptr to camera device struct
255 *
256 * RETURN     : int32_t type of status
257 *              NO_ERROR  -- success
258 *              none-zero failure code
259 *==========================================================================*/
260int QCamera2HardwareInterface::start_preview(struct camera_device *device)
261{
262    int ret = NO_ERROR;
263    QCamera2HardwareInterface *hw =
264        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
265    if (!hw) {
266        ALOGE("NULL camera device");
267        return BAD_VALUE;
268    }
269    ALOGD("[KPI Perf] %s: E", __func__);
270    hw->lockAPI();
271    qcamera_sm_evt_enum_t evt = QCAMERA_SM_EVT_START_PREVIEW;
272    if (hw->isNoDisplayMode()) {
273        evt = QCAMERA_SM_EVT_START_NODISPLAY_PREVIEW;
274    }
275    ret = hw->processAPI(evt, NULL);
276    if (ret == NO_ERROR) {
277        hw->waitAPIResult(evt);
278        ret = hw->m_apiResult.status;
279    }
280    hw->unlockAPI();
281    ALOGD("[KPI Perf] %s: X", __func__);
282    return ret;
283}
284
285/*===========================================================================
286 * FUNCTION   : stop_preview
287 *
288 * DESCRIPTION: stop preview
289 *
290 * PARAMETERS :
291 *   @device  : ptr to camera device struct
292 *
293 * RETURN     : none
294 *==========================================================================*/
295void QCamera2HardwareInterface::stop_preview(struct camera_device *device)
296{
297    QCamera2HardwareInterface *hw =
298        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
299    if (!hw) {
300        ALOGE("NULL camera device");
301        return;
302    }
303    ALOGD("[KPI Perf] %s: E", __func__);
304    hw->lockAPI();
305    int32_t ret = hw->processAPI(QCAMERA_SM_EVT_STOP_PREVIEW, NULL);
306    if (ret == NO_ERROR) {
307        hw->waitAPIResult(QCAMERA_SM_EVT_STOP_PREVIEW);
308    }
309    hw->unlockAPI();
310    ALOGD("[KPI Perf] %s: X", __func__);
311}
312
313/*===========================================================================
314 * FUNCTION   : preview_enabled
315 *
316 * DESCRIPTION: if preview is running
317 *
318 * PARAMETERS :
319 *   @device  : ptr to camera device struct
320 *
321 * RETURN     : 1 -- running
322 *              0 -- not running
323 *==========================================================================*/
324int QCamera2HardwareInterface::preview_enabled(struct camera_device *device)
325{
326    int ret = NO_ERROR;
327    QCamera2HardwareInterface *hw =
328        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
329    if (!hw) {
330        ALOGE("NULL camera device");
331        return BAD_VALUE;
332    }
333
334    hw->lockAPI();
335    ret = hw->processAPI(QCAMERA_SM_EVT_PREVIEW_ENABLED, NULL);
336    if (ret == NO_ERROR) {
337        hw->waitAPIResult(QCAMERA_SM_EVT_PREVIEW_ENABLED);
338        ret = hw->m_apiResult.enabled;
339    }
340    hw->unlockAPI();
341
342    return ret;
343}
344
345/*===========================================================================
346 * FUNCTION   : store_meta_data_in_buffers
347 *
348 * DESCRIPTION: if need to store meta data in buffers for video frame
349 *
350 * PARAMETERS :
351 *   @device  : ptr to camera device struct
352 *   @enable  : flag if enable
353 *
354 * RETURN     : int32_t type of status
355 *              NO_ERROR  -- success
356 *              none-zero failure code
357 *==========================================================================*/
358int QCamera2HardwareInterface::store_meta_data_in_buffers(
359                struct camera_device *device, int enable)
360{
361    int ret = NO_ERROR;
362    QCamera2HardwareInterface *hw =
363        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
364    if (!hw) {
365        ALOGE("NULL camera device");
366        return BAD_VALUE;
367    }
368
369    hw->lockAPI();
370    ret = hw->processAPI(QCAMERA_SM_EVT_STORE_METADATA_IN_BUFS, (void *)enable);
371    if (ret == NO_ERROR) {
372        hw->waitAPIResult(QCAMERA_SM_EVT_STORE_METADATA_IN_BUFS);
373        ret = hw->m_apiResult.status;
374    }
375    hw->unlockAPI();
376
377    return ret;
378}
379
380/*===========================================================================
381 * FUNCTION   : start_recording
382 *
383 * DESCRIPTION: start recording
384 *
385 * PARAMETERS :
386 *   @device  : ptr to camera device struct
387 *
388 * RETURN     : int32_t type of status
389 *              NO_ERROR  -- success
390 *              none-zero failure code
391 *==========================================================================*/
392int QCamera2HardwareInterface::start_recording(struct camera_device *device)
393{
394    int ret = NO_ERROR;
395    QCamera2HardwareInterface *hw =
396        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
397    if (!hw) {
398        ALOGE("NULL camera device");
399        return BAD_VALUE;
400    }
401    ALOGD("[KPI Perf] %s: E", __func__);
402    hw->lockAPI();
403    ret = hw->processAPI(QCAMERA_SM_EVT_START_RECORDING, NULL);
404    if (ret == NO_ERROR) {
405        hw->waitAPIResult(QCAMERA_SM_EVT_START_RECORDING);
406        ret = hw->m_apiResult.status;
407    }
408    hw->unlockAPI();
409    ALOGD("[KPI Perf] %s: X", __func__);
410    return ret;
411}
412
413/*===========================================================================
414 * FUNCTION   : stop_recording
415 *
416 * DESCRIPTION: stop recording
417 *
418 * PARAMETERS :
419 *   @device  : ptr to camera device struct
420 *
421 * RETURN     : none
422 *==========================================================================*/
423void QCamera2HardwareInterface::stop_recording(struct camera_device *device)
424{
425    QCamera2HardwareInterface *hw =
426        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
427    if (!hw) {
428        ALOGE("NULL camera device");
429        return;
430    }
431    ALOGD("[KPI Perf] %s: E", __func__);
432    hw->lockAPI();
433    int32_t ret = hw->processAPI(QCAMERA_SM_EVT_STOP_RECORDING, NULL);
434    if (ret == NO_ERROR) {
435        hw->waitAPIResult(QCAMERA_SM_EVT_STOP_RECORDING);
436    }
437    hw->unlockAPI();
438    ALOGD("[KPI Perf] %s: X", __func__);
439}
440
441/*===========================================================================
442 * FUNCTION   : recording_enabled
443 *
444 * DESCRIPTION: if recording is running
445 *
446 * PARAMETERS :
447 *   @device  : ptr to camera device struct
448 *
449 * RETURN     : 1 -- running
450 *              0 -- not running
451 *==========================================================================*/
452int QCamera2HardwareInterface::recording_enabled(struct camera_device *device)
453{
454    int ret = NO_ERROR;
455    QCamera2HardwareInterface *hw =
456        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
457    if (!hw) {
458        ALOGE("NULL camera device");
459        return BAD_VALUE;
460    }
461    hw->lockAPI();
462    ret = hw->processAPI(QCAMERA_SM_EVT_RECORDING_ENABLED, NULL);
463    if (ret == NO_ERROR) {
464        hw->waitAPIResult(QCAMERA_SM_EVT_RECORDING_ENABLED);
465        ret = hw->m_apiResult.enabled;
466    }
467    hw->unlockAPI();
468
469    return ret;
470}
471
472/*===========================================================================
473 * FUNCTION   : release_recording_frame
474 *
475 * DESCRIPTION: return recording frame back
476 *
477 * PARAMETERS :
478 *   @device  : ptr to camera device struct
479 *   @opaque  : ptr to frame to be returned
480 *
481 * RETURN     : none
482 *==========================================================================*/
483void QCamera2HardwareInterface::release_recording_frame(
484            struct camera_device *device, const void *opaque)
485{
486    QCamera2HardwareInterface *hw =
487        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
488    if (!hw) {
489        ALOGE("NULL camera device");
490        return;
491    }
492    ALOGD("%s: E", __func__);
493    hw->lockAPI();
494    int32_t ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, (void *)opaque);
495    if (ret == NO_ERROR) {
496        hw->waitAPIResult(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME);
497    }
498    hw->unlockAPI();
499    ALOGD("%s: X", __func__);
500}
501
502/*===========================================================================
503 * FUNCTION   : auto_focus
504 *
505 * DESCRIPTION: start auto focus
506 *
507 * PARAMETERS :
508 *   @device  : ptr to camera device struct
509 *
510 * RETURN     : int32_t type of status
511 *              NO_ERROR  -- success
512 *              none-zero failure code
513 *==========================================================================*/
514int QCamera2HardwareInterface::auto_focus(struct camera_device *device)
515{
516    int ret = NO_ERROR;
517    QCamera2HardwareInterface *hw =
518        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
519    if (!hw) {
520        ALOGE("NULL camera device");
521        return BAD_VALUE;
522    }
523    ALOGD("[KPI Perf] %s : E", __func__);
524    hw->lockAPI();
525    ret = hw->processAPI(QCAMERA_SM_EVT_START_AUTO_FOCUS, NULL);
526    if (ret == NO_ERROR) {
527        hw->waitAPIResult(QCAMERA_SM_EVT_START_AUTO_FOCUS);
528        ret = hw->m_apiResult.status;
529    }
530    hw->unlockAPI();
531    ALOGD("[KPI Perf] %s : X", __func__);
532
533    return ret;
534}
535
536/*===========================================================================
537 * FUNCTION   : cancel_auto_focus
538 *
539 * DESCRIPTION: cancel auto focus
540 *
541 * PARAMETERS :
542 *   @device  : ptr to camera device struct
543 *
544 * RETURN     : int32_t type of status
545 *              NO_ERROR  -- success
546 *              none-zero failure code
547 *==========================================================================*/
548int QCamera2HardwareInterface::cancel_auto_focus(struct camera_device *device)
549{
550    int ret = NO_ERROR;
551    QCamera2HardwareInterface *hw =
552        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
553    if (!hw) {
554        ALOGE("NULL camera device");
555        return BAD_VALUE;
556    }
557    hw->lockAPI();
558    ret = hw->processAPI(QCAMERA_SM_EVT_STOP_AUTO_FOCUS, NULL);
559    if (ret == NO_ERROR) {
560        hw->waitAPIResult(QCAMERA_SM_EVT_STOP_AUTO_FOCUS);
561        ret = hw->m_apiResult.status;
562    }
563    hw->unlockAPI();
564
565    return ret;
566}
567
568/*===========================================================================
569 * FUNCTION   : take_picture
570 *
571 * DESCRIPTION: take picture
572 *
573 * PARAMETERS :
574 *   @device  : ptr to camera device struct
575 *
576 * RETURN     : int32_t type of status
577 *              NO_ERROR  -- success
578 *              none-zero failure code
579 *==========================================================================*/
580int QCamera2HardwareInterface::take_picture(struct camera_device *device)
581{
582    int ret = NO_ERROR;
583    QCamera2HardwareInterface *hw =
584        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
585    if (!hw) {
586        ALOGE("NULL camera device");
587        return BAD_VALUE;
588    }
589    ALOGD("[KPI Perf] %s: E", __func__);
590    hw->lockAPI();
591
592    /* Prepare snapshot in case LED needs to be flashed */
593    ret = hw->processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL);
594    if (ret == NO_ERROR) {
595        hw->waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT);
596        ret = hw->m_apiResult.status;
597    }
598
599    /* Regardless what the result value for prepare_snapshot,
600     * go ahead with capture anyway. Just like the way autofocus
601     * is handled in capture case. */
602
603    /* capture */
604    ret = hw->processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL);
605    if (ret == NO_ERROR) {
606        hw->waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE);
607        ret = hw->m_apiResult.status;
608    }
609
610    hw->unlockAPI();
611    ALOGD("[KPI Perf] %s: X", __func__);
612    return ret;
613}
614
615/*===========================================================================
616 * FUNCTION   : cancel_picture
617 *
618 * DESCRIPTION: cancel current take picture request
619 *
620 * PARAMETERS :
621 *   @device  : ptr to camera device struct
622 *
623 * RETURN     : int32_t type of status
624 *              NO_ERROR  -- success
625 *              none-zero failure code
626 *==========================================================================*/
627int QCamera2HardwareInterface::cancel_picture(struct camera_device *device)
628{
629    int ret = NO_ERROR;
630    QCamera2HardwareInterface *hw =
631        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
632    if (!hw) {
633        ALOGE("NULL camera device");
634        return BAD_VALUE;
635    }
636    hw->lockAPI();
637    ret = hw->processAPI(QCAMERA_SM_EVT_CANCEL_PICTURE, NULL);
638    if (ret == NO_ERROR) {
639        hw->waitAPIResult(QCAMERA_SM_EVT_CANCEL_PICTURE);
640        ret = hw->m_apiResult.status;
641    }
642    hw->unlockAPI();
643
644    return ret;
645}
646
647/*===========================================================================
648 * FUNCTION   : set_parameters
649 *
650 * DESCRIPTION: set camera parameters
651 *
652 * PARAMETERS :
653 *   @device  : ptr to camera device struct
654 *   @parms   : string of packed parameters
655 *
656 * RETURN     : int32_t type of status
657 *              NO_ERROR  -- success
658 *              none-zero failure code
659 *==========================================================================*/
660int QCamera2HardwareInterface::set_parameters(struct camera_device *device,
661                                              const char *parms)
662{
663    int ret = NO_ERROR;
664    QCamera2HardwareInterface *hw =
665        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
666    if (!hw) {
667        ALOGE("NULL camera device");
668        return BAD_VALUE;
669    }
670    hw->lockAPI();
671    ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS, (void *)parms);
672    if (ret == NO_ERROR) {
673        hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS);
674        ret = hw->m_apiResult.status;
675    }
676    hw->unlockAPI();
677
678    return ret;
679}
680
681/*===========================================================================
682 * FUNCTION   : get_parameters
683 *
684 * DESCRIPTION: query camera parameters
685 *
686 * PARAMETERS :
687 *   @device  : ptr to camera device struct
688 *
689 * RETURN     : packed parameters in a string
690 *==========================================================================*/
691char* QCamera2HardwareInterface::get_parameters(struct camera_device *device)
692{
693    char *ret = NULL;
694    QCamera2HardwareInterface *hw =
695        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
696    if (!hw) {
697        ALOGE("NULL camera device");
698        return NULL;
699    }
700    hw->lockAPI();
701    int32_t rc = hw->processAPI(QCAMERA_SM_EVT_GET_PARAMS, NULL);
702    if (rc == NO_ERROR) {
703        hw->waitAPIResult(QCAMERA_SM_EVT_GET_PARAMS);
704        ret = hw->m_apiResult.params;
705    }
706    hw->unlockAPI();
707
708    return ret;
709}
710
711/*===========================================================================
712 * FUNCTION   : put_parameters
713 *
714 * DESCRIPTION: return camera parameters string back to HAL
715 *
716 * PARAMETERS :
717 *   @device  : ptr to camera device struct
718 *   @parm    : ptr to parameter string to be returned
719 *
720 * RETURN     : none
721 *==========================================================================*/
722void QCamera2HardwareInterface::put_parameters(struct camera_device *device,
723                                               char *parm)
724{
725    QCamera2HardwareInterface *hw =
726        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
727    if (!hw) {
728        ALOGE("NULL camera device");
729        return;
730    }
731    hw->lockAPI();
732    int32_t ret = hw->processAPI(QCAMERA_SM_EVT_PUT_PARAMS, (void *)parm);
733    if (ret == NO_ERROR) {
734        hw->waitAPIResult(QCAMERA_SM_EVT_PUT_PARAMS);
735    }
736    hw->unlockAPI();
737}
738
739/*===========================================================================
740 * FUNCTION   : send_command
741 *
742 * DESCRIPTION: command to be executed
743 *
744 * PARAMETERS :
745 *   @device  : ptr to camera device struct
746 *   @cmd     : cmd to be executed
747 *   @arg1    : ptr to optional argument1
748 *   @arg2    : ptr to optional argument2
749 *
750 * RETURN     : int32_t type of status
751 *              NO_ERROR  -- success
752 *              none-zero failure code
753 *==========================================================================*/
754int QCamera2HardwareInterface::send_command(struct camera_device *device,
755                                            int32_t cmd,
756                                            int32_t arg1,
757                                            int32_t arg2)
758{
759    int ret = NO_ERROR;
760    QCamera2HardwareInterface *hw =
761        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
762    if (!hw) {
763        ALOGE("NULL camera device");
764        return BAD_VALUE;
765    }
766
767    qcamera_sm_evt_command_payload_t payload;
768    memset(&payload, 0, sizeof(qcamera_sm_evt_command_payload_t));
769    payload.cmd = cmd;
770    payload.arg1 = arg1;
771    payload.arg2 = arg2;
772    hw->lockAPI();
773    ret = hw->processAPI(QCAMERA_SM_EVT_SEND_COMMAND, (void *)&payload);
774    if (ret == NO_ERROR) {
775        hw->waitAPIResult(QCAMERA_SM_EVT_SEND_COMMAND);
776        ret = hw->m_apiResult.status;
777    }
778    hw->unlockAPI();
779
780    return ret;
781}
782
783/*===========================================================================
784 * FUNCTION   : release
785 *
786 * DESCRIPTION: release camera resource
787 *
788 * PARAMETERS :
789 *   @device  : ptr to camera device struct
790 *
791 * RETURN     : none
792 *==========================================================================*/
793void QCamera2HardwareInterface::release(struct camera_device *device)
794{
795    QCamera2HardwareInterface *hw =
796        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
797    if (!hw) {
798        ALOGE("NULL camera device");
799        return;
800    }
801    hw->lockAPI();
802    int32_t ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE, NULL);
803    if (ret == NO_ERROR) {
804        hw->waitAPIResult(QCAMERA_SM_EVT_RELEASE);
805    }
806    hw->unlockAPI();
807}
808
809/*===========================================================================
810 * FUNCTION   : dump
811 *
812 * DESCRIPTION: dump camera status
813 *
814 * PARAMETERS :
815 *   @device  : ptr to camera device struct
816 *   @fd      : fd for status to be dumped to
817 *
818 * RETURN     : int32_t type of status
819 *              NO_ERROR  -- success
820 *              none-zero failure code
821 *==========================================================================*/
822int QCamera2HardwareInterface::dump(struct camera_device *device, int fd)
823{
824    int ret = NO_ERROR;
825    QCamera2HardwareInterface *hw =
826        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
827    if (!hw) {
828        ALOGE("NULL camera device");
829        return BAD_VALUE;
830    }
831    hw->lockAPI();
832    ret = hw->processAPI(QCAMERA_SM_EVT_DUMP, (void *)fd);
833    if (ret == NO_ERROR) {
834        hw->waitAPIResult(QCAMERA_SM_EVT_DUMP);
835        ret = hw->m_apiResult.status;
836    }
837    hw->unlockAPI();
838
839    return ret;
840}
841
842/*===========================================================================
843 * FUNCTION   : close_camera_device
844 *
845 * DESCRIPTION: close camera device
846 *
847 * PARAMETERS :
848 *   @device  : ptr to camera device struct
849 *
850 * RETURN     : int32_t type of status
851 *              NO_ERROR  -- success
852 *              none-zero failure code
853 *==========================================================================*/
854int QCamera2HardwareInterface::close_camera_device(hw_device_t *hw_dev)
855{
856    int ret = NO_ERROR;
857    ALOGD("[KPI Perf] %s: E",__func__);
858    QCamera2HardwareInterface *hw =
859        reinterpret_cast<QCamera2HardwareInterface *>(
860            reinterpret_cast<camera_device_t *>(hw_dev)->priv);
861    if (!hw) {
862        ALOGE("%s: NULL camera device", __func__);
863        return BAD_VALUE;
864    }
865    delete hw;
866    ALOGD("[KPI Perf] %s: X",__func__);
867    return ret;
868}
869
870/*===========================================================================
871 * FUNCTION   : register_face_image
872 *
873 * DESCRIPTION: register a face image into imaging lib for face authenticatio/
874 *              face recognition
875 *
876 * PARAMETERS :
877 *   @device  : ptr to camera device struct
878 *   @img_ptr : ptr to image buffer
879 *   @config  : ptr to config about input image, i.e., format, dimension, and etc.
880 *
881 * RETURN     : >=0 unique ID of face registerd.
882 *              <0  failure.
883 *==========================================================================*/
884int QCamera2HardwareInterface::register_face_image(struct camera_device *device,
885                                                   void *img_ptr,
886                                                   cam_pp_offline_src_config_t *config)
887{
888    int ret = NO_ERROR;
889    QCamera2HardwareInterface *hw =
890        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
891    if (!hw) {
892        ALOGE("NULL camera device");
893        return BAD_VALUE;
894    }
895    qcamera_sm_evt_reg_face_payload_t payload;
896    memset(&payload, 0, sizeof(qcamera_sm_evt_reg_face_payload_t));
897    payload.img_ptr = img_ptr;
898    payload.config = config;
899    hw->lockAPI();
900    ret = hw->processAPI(QCAMERA_SM_EVT_REG_FACE_IMAGE, (void *)&payload);
901    if (ret == NO_ERROR) {
902        hw->waitAPIResult(QCAMERA_SM_EVT_REG_FACE_IMAGE);
903        ret = hw->m_apiResult.handle;
904    }
905    hw->unlockAPI();
906
907    return ret;
908}
909
910/*===========================================================================
911 * FUNCTION   : QCamera2HardwareInterface
912 *
913 * DESCRIPTION: constructor of QCamera2HardwareInterface
914 *
915 * PARAMETERS :
916 *   @cameraId  : camera ID
917 *
918 * RETURN     : none
919 *==========================================================================*/
920QCamera2HardwareInterface::QCamera2HardwareInterface(int cameraId)
921    : mCameraId(cameraId),
922      mCameraHandle(NULL),
923      mCameraOpened(false),
924      mPreviewWindow(NULL),
925      mMsgEnabled(0),
926      mStoreMetaDataInFrame(0),
927      m_stateMachine(this),
928      m_postprocessor(this),
929      m_thermalAdapter(QCameraThermalAdapter::getInstance()),
930      m_cbNotifier(this),
931      m_bShutterSoundPlayed(false),
932      m_currentFocusState(CAM_AF_NOT_FOCUSED),
933      m_bStartZSLSnapshotCalled(false),
934      m_pPowerModule(NULL),
935      mDumpFrmCnt(0),
936      mDumpSkipCnt(0)
937{
938    mCameraDevice.common.tag = HARDWARE_DEVICE_TAG;
939    mCameraDevice.common.version = HARDWARE_DEVICE_API_VERSION(1, 0);
940    mCameraDevice.common.close = close_camera_device;
941    mCameraDevice.ops = &mCameraOps;
942    mCameraDevice.priv = this;
943
944
945    pthread_mutex_init(&m_lock, NULL);
946    pthread_cond_init(&m_cond, NULL);
947    memset(&m_apiResult, 0, sizeof(qcamera_api_result_t));
948
949    pthread_mutex_init(&m_evtLock, NULL);
950    pthread_cond_init(&m_evtCond, NULL);
951    memset(&m_evtResult, 0, sizeof(qcamera_api_result_t));
952
953    memset(m_channels, 0, sizeof(m_channels));
954
955#ifdef HAS_MULTIMEDIA_HINTS
956    if (hw_get_module(POWER_HARDWARE_MODULE_ID, (const hw_module_t **)&m_pPowerModule)) {
957        ALOGE("%s: %s module not found", __func__, POWER_HARDWARE_MODULE_ID);
958    }
959#endif
960
961}
962
963/*===========================================================================
964 * FUNCTION   : ~QCamera2HardwareInterface
965 *
966 * DESCRIPTION: destructor of QCamera2HardwareInterface
967 *
968 * PARAMETERS : none
969 *
970 * RETURN     : none
971 *==========================================================================*/
972QCamera2HardwareInterface::~QCamera2HardwareInterface()
973{
974    closeCamera();
975    pthread_mutex_destroy(&m_lock);
976    pthread_cond_destroy(&m_cond);
977    pthread_mutex_destroy(&m_evtLock);
978    pthread_cond_destroy(&m_evtCond);
979}
980
981/*===========================================================================
982 * FUNCTION   : openCamera
983 *
984 * DESCRIPTION: open camera
985 *
986 * PARAMETERS :
987 *   @hw_device  : double ptr for camera device struct
988 *
989 * RETURN     : int32_t type of status
990 *              NO_ERROR  -- success
991 *              none-zero failure code
992 *==========================================================================*/
993int QCamera2HardwareInterface::openCamera(struct hw_device_t **hw_device)
994{
995    int rc = NO_ERROR;
996    if (mCameraOpened) {
997        *hw_device = NULL;
998        return PERMISSION_DENIED;
999    }
1000
1001    rc = openCamera();
1002    if (rc == NO_ERROR)
1003        *hw_device = &mCameraDevice.common;
1004    else
1005        *hw_device = NULL;
1006    return rc;
1007}
1008
1009/*===========================================================================
1010 * FUNCTION   : openCamera
1011 *
1012 * DESCRIPTION: open camera
1013 *
1014 * PARAMETERS : none
1015 *
1016 * RETURN     : int32_t type of status
1017 *              NO_ERROR  -- success
1018 *              none-zero failure code
1019 *==========================================================================*/
1020int QCamera2HardwareInterface::openCamera()
1021{
1022    if (mCameraHandle) {
1023        ALOGE("Failure: Camera already opened");
1024        return ALREADY_EXISTS;
1025    }
1026    mCameraHandle = camera_open(mCameraId);
1027    if (!mCameraHandle) {
1028        ALOGE("camera_open failed.");
1029        return UNKNOWN_ERROR;
1030    }
1031
1032    mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle,
1033                                              camEvtHandle,
1034                                              (void *) this);
1035
1036    int32_t rc = m_postprocessor.init(jpegEvtHandle, this);
1037    if (rc != 0) {
1038        ALOGE("Init Postprocessor failed");
1039        return UNKNOWN_ERROR;
1040    }
1041
1042    // update padding info from jpeg
1043    cam_padding_info_t padding_info;
1044    m_postprocessor.getJpegPaddingReq(padding_info);
1045    if (gCamCapability[mCameraId]->padding_info.width_padding < padding_info.width_padding) {
1046        gCamCapability[mCameraId]->padding_info.width_padding = padding_info.width_padding;
1047    }
1048    if (gCamCapability[mCameraId]->padding_info.height_padding < padding_info.height_padding) {
1049        gCamCapability[mCameraId]->padding_info.height_padding = padding_info.height_padding;
1050    }
1051    if (gCamCapability[mCameraId]->padding_info.plane_padding < padding_info.plane_padding) {
1052        gCamCapability[mCameraId]->padding_info.plane_padding = padding_info.plane_padding;
1053    }
1054
1055    mParameters.init(gCamCapability[mCameraId], mCameraHandle);
1056
1057    rc = m_thermalAdapter.init(this);
1058    if (rc != 0) {
1059        ALOGE("Init thermal adapter failed");
1060    }
1061
1062    mCameraOpened = true;
1063
1064    return NO_ERROR;
1065}
1066
1067/*===========================================================================
1068 * FUNCTION   : closeCamera
1069 *
1070 * DESCRIPTION: close camera
1071 *
1072 * PARAMETERS : none
1073 *
1074 * RETURN     : int32_t type of status
1075 *              NO_ERROR  -- success
1076 *              none-zero failure code
1077 *==========================================================================*/
1078int QCamera2HardwareInterface::closeCamera()
1079{
1080    int rc = NO_ERROR;
1081    int i;
1082
1083    // deinit Parameters
1084    mParameters.deinit();
1085
1086    // stop and deinit postprocessor
1087    m_postprocessor.stop();
1088    m_postprocessor.deinit();
1089
1090    m_thermalAdapter.deinit();
1091
1092    // delete all channels if not already deleted
1093    for (i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
1094        if (m_channels[i] != NULL) {
1095            m_channels[i]->stop();
1096            delete m_channels[i];
1097            m_channels[i] = NULL;
1098        }
1099    }
1100
1101    rc = mCameraHandle->ops->close_camera(mCameraHandle->camera_handle);
1102    mCameraHandle = NULL;
1103    mCameraOpened = false;
1104
1105    return rc;
1106}
1107
1108#define DATA_PTR(MEM_OBJ,INDEX) MEM_OBJ->getPtr( INDEX )
1109
1110/*===========================================================================
1111 * FUNCTION   : initCapabilities
1112 *
1113 * DESCRIPTION: initialize camera capabilities in static data struct
1114 *
1115 * PARAMETERS :
1116 *   @cameraId  : camera Id
1117 *
1118 * RETURN     : int32_t type of status
1119 *              NO_ERROR  -- success
1120 *              none-zero failure code
1121 *==========================================================================*/
1122int QCamera2HardwareInterface::initCapabilities(int cameraId)
1123{
1124    int rc = NO_ERROR;
1125    mm_camera_vtbl_t *cameraHandle = NULL;
1126    QCameraHeapMemory *capabilityHeap = NULL;
1127
1128    cameraHandle = camera_open(cameraId);
1129    if (!cameraHandle) {
1130        ALOGE("%s: camera_open failed", __func__);
1131        rc = UNKNOWN_ERROR;
1132        goto open_failed;
1133    }
1134
1135    /* Allocate memory for capability buffer */
1136    capabilityHeap = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
1137    rc = capabilityHeap->allocate(1, sizeof(cam_capability_t));
1138    if(rc != OK) {
1139        ALOGE("%s: No memory for cappability", __func__);
1140        goto allocate_failed;
1141    }
1142
1143    /* Map memory for capability buffer */
1144    memset(DATA_PTR(capabilityHeap,0), 0, sizeof(cam_capability_t));
1145    rc = cameraHandle->ops->map_buf(cameraHandle->camera_handle,
1146                                CAM_MAPPING_BUF_TYPE_CAPABILITY,
1147                                capabilityHeap->getFd(0),
1148                                sizeof(cam_capability_t));
1149    if(rc < 0) {
1150        ALOGE("%s: failed to map capability buffer", __func__);
1151        goto map_failed;
1152    }
1153
1154    /* Query Capability */
1155    rc = cameraHandle->ops->query_capability(cameraHandle->camera_handle);
1156    if(rc < 0) {
1157        ALOGE("%s: failed to query capability",__func__);
1158        goto query_failed;
1159    }
1160    gCamCapability[cameraId] = (cam_capability_t *)malloc(sizeof(cam_capability_t));
1161    if (!gCamCapability[cameraId]) {
1162        ALOGE("%s: out of memory", __func__);
1163        goto query_failed;
1164    }
1165    memcpy(gCamCapability[cameraId], DATA_PTR(capabilityHeap,0),
1166                                        sizeof(cam_capability_t));
1167
1168    rc = NO_ERROR;
1169
1170query_failed:
1171    cameraHandle->ops->unmap_buf(cameraHandle->camera_handle,
1172                            CAM_MAPPING_BUF_TYPE_CAPABILITY);
1173map_failed:
1174    capabilityHeap->deallocate();
1175    delete capabilityHeap;
1176allocate_failed:
1177    cameraHandle->ops->close_camera(cameraHandle->camera_handle);
1178    cameraHandle = NULL;
1179open_failed:
1180    return rc;
1181}
1182
1183/*===========================================================================
1184 * FUNCTION   : getCapabilities
1185 *
1186 * DESCRIPTION: query camera capabilities
1187 *
1188 * PARAMETERS :
1189 *   @cameraId  : camera Id
1190 *   @info      : camera info struct to be filled in with camera capabilities
1191 *
1192 * RETURN     : int32_t type of status
1193 *              NO_ERROR  -- success
1194 *              none-zero failure code
1195 *==========================================================================*/
1196int QCamera2HardwareInterface::getCapabilities(int cameraId,
1197                                    struct camera_info *info)
1198{
1199    int rc = NO_ERROR;
1200
1201    pthread_mutex_lock(&g_camlock);
1202    if (NULL == gCamCapability[cameraId]) {
1203        rc = initCapabilities(cameraId);
1204        if (rc < 0) {
1205            pthread_mutex_unlock(&g_camlock);
1206            return rc;
1207        }
1208    }
1209
1210    switch(gCamCapability[cameraId]->position) {
1211    case CAM_POSITION_BACK:
1212        info->facing = CAMERA_FACING_BACK;
1213        break;
1214
1215    case CAM_POSITION_FRONT:
1216        info->facing = CAMERA_FACING_FRONT;
1217        break;
1218
1219    default:
1220        ALOGE("%s:Unknown position type for camera id:%d", __func__, cameraId);
1221        rc = BAD_VALUE;
1222        break;
1223    }
1224
1225    info->orientation = gCamCapability[cameraId]->sensor_mount_angle;
1226    pthread_mutex_unlock(&g_camlock);
1227    return rc;
1228}
1229
1230/*===========================================================================
1231 * FUNCTION   : getBufNumRequired
1232 *
1233 * DESCRIPTION: return number of stream buffers needed for given stream type
1234 *
1235 * PARAMETERS :
1236 *   @stream_type  : type of stream
1237 *
1238 * RETURN     : number of buffers needed
1239 *==========================================================================*/
1240uint8_t QCamera2HardwareInterface::getBufNumRequired(cam_stream_type_t stream_type)
1241{
1242    int bufferCnt = 0;
1243    int minCaptureBuffers = mParameters.getNumOfSnapshots();
1244
1245    int zslQBuffers = mParameters.getZSLQueueDepth() +
1246                      mParameters.getMaxUnmatchedFramesInQueue();
1247
1248    int minCircularBufNum = CAMERA_MIN_STREAMING_BUFFERS +
1249                            CAMERA_MIN_JPEG_ENCODING_BUFFERS +
1250                            mParameters.getMaxUnmatchedFramesInQueue() +
1251                            mParameters.getNumOfHDRBufsIfNeeded();
1252
1253    // Get buffer count for the particular stream type
1254    switch (stream_type) {
1255    case CAM_STREAM_TYPE_PREVIEW:
1256        {
1257            if (mParameters.isZSLMode()) {
1258                bufferCnt = zslQBuffers + minCircularBufNum;
1259            } else {
1260                bufferCnt = CAMERA_MIN_STREAMING_BUFFERS +
1261                            mParameters.getMaxUnmatchedFramesInQueue();
1262            }
1263        }
1264        break;
1265    case CAM_STREAM_TYPE_POSTVIEW:
1266        {
1267            bufferCnt = minCaptureBuffers +
1268                        mParameters.getMaxUnmatchedFramesInQueue() +
1269                        mParameters.getNumOfExtraHDRBufsIfNeeded() +
1270                        CAMERA_MIN_STREAMING_BUFFERS;
1271        }
1272        break;
1273    case CAM_STREAM_TYPE_SNAPSHOT:
1274        {
1275            if (mParameters.isZSLMode()) {
1276                bufferCnt = zslQBuffers + minCircularBufNum;
1277            } else {
1278                bufferCnt = minCaptureBuffers +
1279                            mParameters.getMaxUnmatchedFramesInQueue() +
1280                            mParameters.getNumOfExtraHDRBufsIfNeeded() +
1281                            CAMERA_MIN_STREAMING_BUFFERS;
1282            }
1283        }
1284        break;
1285    case CAM_STREAM_TYPE_RAW:
1286        if (mParameters.isZSLMode()) {
1287            bufferCnt = zslQBuffers + CAMERA_MIN_STREAMING_BUFFERS;
1288        } else {
1289            bufferCnt = minCaptureBuffers +
1290                        mParameters.getMaxUnmatchedFramesInQueue() +
1291                        mParameters.getNumOfExtraHDRBufsIfNeeded() +
1292                        CAMERA_MIN_STREAMING_BUFFERS;
1293        }
1294        break;
1295    case CAM_STREAM_TYPE_VIDEO:
1296        {
1297            bufferCnt = CAMERA_MIN_VIDEO_BUFFERS +
1298                        mParameters.getMaxUnmatchedFramesInQueue() +
1299                        CAMERA_MIN_STREAMING_BUFFERS;
1300        }
1301        break;
1302    case CAM_STREAM_TYPE_METADATA:
1303        {
1304            bufferCnt = minCaptureBuffers +
1305                        mParameters.getMaxUnmatchedFramesInQueue() +
1306                        mParameters.getNumOfExtraHDRBufsIfNeeded() +
1307                        CAMERA_MIN_STREAMING_BUFFERS;
1308            if (bufferCnt < zslQBuffers + minCircularBufNum) {
1309                bufferCnt = zslQBuffers + minCircularBufNum;
1310            }
1311        }
1312        break;
1313    case CAM_STREAM_TYPE_OFFLINE_PROC:
1314        {
1315            bufferCnt = minCaptureBuffers +
1316                        mParameters.getMaxUnmatchedFramesInQueue();
1317            if (bufferCnt < CAMERA_MIN_STREAMING_BUFFERS) {
1318                bufferCnt = CAMERA_MIN_STREAMING_BUFFERS;
1319            }
1320        }
1321        break;
1322    case CAM_STREAM_TYPE_DEFAULT:
1323    case CAM_STREAM_TYPE_MAX:
1324    default:
1325        bufferCnt = 0;
1326        break;
1327    }
1328
1329    return bufferCnt;
1330}
1331
1332/*===========================================================================
1333 * FUNCTION   : allocateStreamBuf
1334 *
1335 * DESCRIPTION: alocate stream buffers
1336 *
1337 * PARAMETERS :
1338 *   @stream_type  : type of stream
1339 *   @size         : size of buffer
1340 *   @bufferCnt    : [IN/OUT] minimum num of buffers to be allocated.
1341 *                   could be modified during allocation if more buffers needed
1342 *
1343 * RETURN     : ptr to a memory obj that holds stream buffers.
1344 *              NULL if failed
1345 *==========================================================================*/
1346QCameraMemory *QCamera2HardwareInterface::allocateStreamBuf(cam_stream_type_t stream_type,
1347                                                            int size,
1348                                                            uint8_t &bufferCnt)
1349{
1350    int rc = NO_ERROR;
1351    QCameraMemory *mem = NULL;
1352    bool bCachedMem = QCAMERA_ION_USE_CACHE;
1353
1354    // Allocate stream buffer memory object
1355    switch (stream_type) {
1356    case CAM_STREAM_TYPE_PREVIEW:
1357        {
1358            if (isNoDisplayMode()) {
1359                mem = new QCameraStreamMemory(mGetMemory, bCachedMem);
1360            } else {
1361                cam_dimension_t dim;
1362                QCameraGrallocMemory *grallocMemory =
1363                    new QCameraGrallocMemory(mGetMemory);
1364
1365                mParameters.getStreamDimension(stream_type, dim);
1366                if (grallocMemory)
1367                    grallocMemory->setWindowInfo(mPreviewWindow, dim.width, dim.height,
1368                            mParameters.getPreviewHalPixelFormat());
1369                mem = grallocMemory;
1370            }
1371        }
1372        break;
1373    case CAM_STREAM_TYPE_POSTVIEW:
1374        {
1375            cam_dimension_t dim;
1376            QCameraGrallocMemory *grallocMemory =
1377                new QCameraGrallocMemory(mGetMemory);
1378
1379            mParameters.getStreamDimension(stream_type, dim);
1380            if (grallocMemory)
1381                grallocMemory->setWindowInfo(mPreviewWindow, dim.width, dim.height,
1382                        mParameters.getPreviewHalPixelFormat());
1383            mem = grallocMemory;
1384        }
1385        break;
1386    case CAM_STREAM_TYPE_SNAPSHOT:
1387    case CAM_STREAM_TYPE_RAW:
1388    case CAM_STREAM_TYPE_METADATA:
1389    case CAM_STREAM_TYPE_OFFLINE_PROC:
1390        mem = new QCameraStreamMemory(mGetMemory, bCachedMem);
1391        break;
1392    case CAM_STREAM_TYPE_VIDEO:
1393        {
1394            char value[32];
1395            property_get("persist.camera.mem.usecache", value, "1");
1396            if (atoi(value) == 0) {
1397                bCachedMem = QCAMERA_ION_USE_NOCACHE;
1398            }
1399            ALOGD("%s: vidoe buf using cached memory = %d", __func__, bCachedMem);
1400            mem = new QCameraVideoMemory(mGetMemory, bCachedMem);
1401        }
1402        break;
1403    case CAM_STREAM_TYPE_DEFAULT:
1404    case CAM_STREAM_TYPE_MAX:
1405    default:
1406        break;
1407    }
1408    if (!mem) {
1409        return NULL;
1410    }
1411
1412    if (bufferCnt > 0) {
1413        rc = mem->allocate(bufferCnt, size);
1414        if (rc < 0) {
1415            delete mem;
1416            return NULL;
1417        }
1418        bufferCnt = mem->getCnt();
1419    }
1420    return mem;
1421}
1422
1423/*===========================================================================
1424 * FUNCTION   : allocateStreamInfoBuf
1425 *
1426 * DESCRIPTION: alocate stream info buffer
1427 *
1428 * PARAMETERS :
1429 *   @stream_type  : type of stream
1430 *
1431 * RETURN     : ptr to a memory obj that holds stream info buffer.
1432 *              NULL if failed
1433 *==========================================================================*/
1434QCameraHeapMemory *QCamera2HardwareInterface::allocateStreamInfoBuf(
1435    cam_stream_type_t stream_type)
1436{
1437    int rc = NO_ERROR;
1438
1439    QCameraHeapMemory *streamInfoBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
1440    if (!streamInfoBuf) {
1441        ALOGE("allocateStreamInfoBuf: Unable to allocate streamInfo object");
1442        return NULL;
1443    }
1444
1445    rc = streamInfoBuf->allocate(1, sizeof(cam_stream_info_t));
1446    if (rc < 0) {
1447        ALOGE("allocateStreamInfoBuf: Failed to allocate stream info memory");
1448        delete streamInfoBuf;
1449        return NULL;
1450    }
1451
1452    cam_stream_info_t *streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(0);
1453    memset(streamInfo, 0, sizeof(cam_stream_info_t));
1454    streamInfo->stream_type = stream_type;
1455    rc = mParameters.getStreamFormat(stream_type, streamInfo->fmt);
1456    rc = mParameters.getStreamDimension(stream_type, streamInfo->dim);
1457
1458    streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
1459    switch (stream_type) {
1460    case CAM_STREAM_TYPE_SNAPSHOT:
1461    case CAM_STREAM_TYPE_RAW:
1462        if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) {
1463            streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
1464        } else {
1465            streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
1466            streamInfo->num_of_burst = mParameters.getNumOfSnapshots();
1467        }
1468        break;
1469    case CAM_STREAM_TYPE_POSTVIEW:
1470        streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
1471        streamInfo->num_of_burst = mParameters.getNumOfSnapshots();
1472        break;
1473    default:
1474        break;
1475    }
1476
1477    //set flip mode based on Stream type;
1478    int flipMode = mParameters.getFlipMode(stream_type);
1479    if (flipMode > 0) {
1480        streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_FLIP;
1481        streamInfo->pp_config.flip = flipMode;
1482    }
1483
1484    return streamInfoBuf;
1485}
1486
1487/*===========================================================================
1488 * FUNCTION   : setPreviewWindow
1489 *
1490 * DESCRIPTION: set preview window impl
1491 *
1492 * PARAMETERS :
1493 *   @window  : ptr to window ops table struct
1494 *
1495 * RETURN     : int32_t type of status
1496 *              NO_ERROR  -- success
1497 *              none-zero failure code
1498 *==========================================================================*/
1499int QCamera2HardwareInterface::setPreviewWindow(
1500        struct preview_stream_ops *window)
1501{
1502    mPreviewWindow = window;
1503    return NO_ERROR;
1504}
1505
1506/*===========================================================================
1507 * FUNCTION   : setCallBacks
1508 *
1509 * DESCRIPTION: set callbacks impl
1510 *
1511 * PARAMETERS :
1512 *   @notify_cb  : notify cb
1513 *   @data_cb    : data cb
1514 *   @data_cb_timestamp : data cb with time stamp
1515 *   @get_memory : request memory ops table
1516 *   @user       : user data ptr
1517 *
1518 * RETURN     : int32_t type of status
1519 *              NO_ERROR  -- success
1520 *              none-zero failure code
1521 *==========================================================================*/
1522int QCamera2HardwareInterface::setCallBacks(camera_notify_callback notify_cb,
1523                                            camera_data_callback data_cb,
1524                                            camera_data_timestamp_callback data_cb_timestamp,
1525                                            camera_request_memory get_memory,
1526                                            void *user)
1527{
1528    mNotifyCb        = notify_cb;
1529    mDataCb          = data_cb;
1530    mDataCbTimestamp = data_cb_timestamp;
1531    mGetMemory       = get_memory;
1532    mCallbackCookie  = user;
1533    m_cbNotifier.setCallbacks(notify_cb, data_cb, data_cb_timestamp, user);
1534    return NO_ERROR;
1535}
1536
1537/*===========================================================================
1538 * FUNCTION   : enableMsgType
1539 *
1540 * DESCRIPTION: enable msg type impl
1541 *
1542 * PARAMETERS :
1543 *   @msg_type  : msg type mask to be enabled
1544 *
1545 * RETURN     : int32_t type of status
1546 *              NO_ERROR  -- success
1547 *              none-zero failure code
1548 *==========================================================================*/
1549int QCamera2HardwareInterface::enableMsgType(int32_t msg_type)
1550{
1551    mMsgEnabled |= msg_type;
1552    return NO_ERROR;
1553}
1554
1555/*===========================================================================
1556 * FUNCTION   : disableMsgType
1557 *
1558 * DESCRIPTION: disable msg type impl
1559 *
1560 * PARAMETERS :
1561 *   @msg_type  : msg type mask to be disabled
1562 *
1563 * RETURN     : int32_t type of status
1564 *              NO_ERROR  -- success
1565 *              none-zero failure code
1566 *==========================================================================*/
1567int QCamera2HardwareInterface::disableMsgType(int32_t msg_type)
1568{
1569    mMsgEnabled &= ~msg_type;
1570    return NO_ERROR;
1571}
1572
1573/*===========================================================================
1574 * FUNCTION   : msgTypeEnabled
1575 *
1576 * DESCRIPTION: impl to determine if certain msg_type is enabled
1577 *
1578 * PARAMETERS :
1579 *   @msg_type  : msg type mask
1580 *
1581 * RETURN     : 0 -- not enabled
1582 *              none 0 -- enabled
1583 *==========================================================================*/
1584int QCamera2HardwareInterface::msgTypeEnabled(int32_t msg_type)
1585{
1586    return (mMsgEnabled & msg_type);
1587}
1588
1589/*===========================================================================
1590 * FUNCTION   : msgTypeEnabledWithLock
1591 *
1592 * DESCRIPTION: impl to determine if certain msg_type is enabled with lock
1593 *
1594 * PARAMETERS :
1595 *   @msg_type  : msg type mask
1596 *
1597 * RETURN     : 0 -- not enabled
1598 *              none 0 -- enabled
1599 *==========================================================================*/
1600int QCamera2HardwareInterface::msgTypeEnabledWithLock(int32_t msg_type)
1601{
1602    int enabled = 0;
1603    lockAPI();
1604    enabled = mMsgEnabled & msg_type;
1605    unlockAPI();
1606    return enabled;
1607}
1608
1609/*===========================================================================
1610 * FUNCTION   : startPreview
1611 *
1612 * DESCRIPTION: start preview impl
1613 *
1614 * PARAMETERS : none
1615 *
1616 * RETURN     : int32_t type of status
1617 *              NO_ERROR  -- success
1618 *              none-zero failure code
1619 *==========================================================================*/
1620int QCamera2HardwareInterface::startPreview()
1621{
1622    int32_t rc = NO_ERROR;
1623    ALOGD("%s: E", __func__);
1624    // start preview stream
1625    if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() !=true) {
1626        rc = startChannel(QCAMERA_CH_TYPE_ZSL);
1627    } else {
1628        rc = startChannel(QCAMERA_CH_TYPE_PREVIEW);
1629    }
1630    ALOGD("%s: X", __func__);
1631    return rc;
1632}
1633
1634/*===========================================================================
1635 * FUNCTION   : stopPreview
1636 *
1637 * DESCRIPTION: stop preview impl
1638 *
1639 * PARAMETERS : none
1640 *
1641 * RETURN     : int32_t type of status
1642 *              NO_ERROR  -- success
1643 *              none-zero failure code
1644 *==========================================================================*/
1645int QCamera2HardwareInterface::stopPreview()
1646{
1647    ALOGD("%s: E", __func__);
1648    // stop preview stream
1649    if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() !=true) {
1650        stopChannel(QCAMERA_CH_TYPE_ZSL);
1651    } else {
1652        stopChannel(QCAMERA_CH_TYPE_PREVIEW);
1653    }
1654
1655    // delete all channels from preparePreview
1656    unpreparePreview();
1657    ALOGD("%s: X", __func__);
1658    return NO_ERROR;
1659}
1660
1661/*===========================================================================
1662 * FUNCTION   : storeMetaDataInBuffers
1663 *
1664 * DESCRIPTION: enable store meta data in buffers for video frames impl
1665 *
1666 * PARAMETERS :
1667 *   @enable  : flag if need enable
1668 *
1669 * RETURN     : int32_t type of status
1670 *              NO_ERROR  -- success
1671 *              none-zero failure code
1672 *==========================================================================*/
1673int QCamera2HardwareInterface::storeMetaDataInBuffers(int enable)
1674{
1675    mStoreMetaDataInFrame = enable;
1676    return NO_ERROR;
1677}
1678
1679/*===========================================================================
1680 * FUNCTION   : startRecording
1681 *
1682 * DESCRIPTION: start recording impl
1683 *
1684 * PARAMETERS : none
1685 *
1686 * RETURN     : int32_t type of status
1687 *              NO_ERROR  -- success
1688 *              none-zero failure code
1689 *==========================================================================*/
1690int QCamera2HardwareInterface::startRecording()
1691{
1692    int32_t rc = NO_ERROR;
1693    ALOGD("%s: E", __func__);
1694    if (mParameters.getRecordingHintValue() == false) {
1695        ALOGE("%s: start recording when hint is false, stop preview first", __func__);
1696        stopChannel(QCAMERA_CH_TYPE_PREVIEW);
1697        delChannel(QCAMERA_CH_TYPE_PREVIEW);
1698
1699        // Set recording hint to TRUE
1700        mParameters.updateRecordingHintValue(TRUE);
1701        rc = preparePreview();
1702        if (rc == NO_ERROR) {
1703            rc = startChannel(QCAMERA_CH_TYPE_PREVIEW);
1704        }
1705    }
1706
1707    if (rc == NO_ERROR) {
1708        rc = startChannel(QCAMERA_CH_TYPE_VIDEO);
1709    }
1710
1711#ifdef HAS_MULTIMEDIA_HINTS
1712    if (rc == NO_ERROR) {
1713        if (m_pPowerModule) {
1714            if (m_pPowerModule->powerHint) {
1715                m_pPowerModule->powerHint(m_pPowerModule, POWER_HINT_VIDEO_ENCODE, (void *)"state=1");
1716            }
1717        }
1718    }
1719#endif
1720    ALOGD("%s: X", __func__);
1721    return rc;
1722}
1723
1724/*===========================================================================
1725 * FUNCTION   : stopRecording
1726 *
1727 * DESCRIPTION: stop recording impl
1728 *
1729 * PARAMETERS : none
1730 *
1731 * RETURN     : int32_t type of status
1732 *              NO_ERROR  -- success
1733 *              none-zero failure code
1734 *==========================================================================*/
1735int QCamera2HardwareInterface::stopRecording()
1736{
1737    int rc = stopChannel(QCAMERA_CH_TYPE_VIDEO);
1738    ALOGD("%s: E", __func__);
1739#ifdef HAS_MULTIMEDIA_HINTS
1740    if (m_pPowerModule) {
1741        if (m_pPowerModule->powerHint) {
1742            m_pPowerModule->powerHint(m_pPowerModule, POWER_HINT_VIDEO_ENCODE, (void *)"state=0");
1743        }
1744    }
1745#endif
1746    ALOGD("%s: X", __func__);
1747    return rc;
1748}
1749
1750/*===========================================================================
1751 * FUNCTION   : releaseRecordingFrame
1752 *
1753 * DESCRIPTION: return video frame impl
1754 *
1755 * PARAMETERS :
1756 *   @opaque  : ptr to video frame to be returned
1757 *
1758 * RETURN     : int32_t type of status
1759 *              NO_ERROR  -- success
1760 *              none-zero failure code
1761 *==========================================================================*/
1762int QCamera2HardwareInterface::releaseRecordingFrame(const void * opaque)
1763{
1764    int32_t rc = UNKNOWN_ERROR;
1765    QCameraVideoChannel *pChannel =
1766        (QCameraVideoChannel *)m_channels[QCAMERA_CH_TYPE_VIDEO];
1767    ALOGD("%s: opaque data = %p", __func__,opaque);
1768    if(pChannel != NULL) {
1769        rc = pChannel->releaseFrame(opaque, mStoreMetaDataInFrame > 0);
1770    }
1771    return rc;
1772}
1773
1774/*===========================================================================
1775 * FUNCTION   : autoFocus
1776 *
1777 * DESCRIPTION: start auto focus impl
1778 *
1779 * PARAMETERS : none
1780 *
1781 * RETURN     : int32_t type of status
1782 *              NO_ERROR  -- success
1783 *              none-zero failure code
1784 *==========================================================================*/
1785int QCamera2HardwareInterface::autoFocus()
1786{
1787    int rc = NO_ERROR;
1788    cam_focus_mode_type focusMode = mParameters.getFocusMode();
1789
1790    switch (focusMode) {
1791    case CAM_FOCUS_MODE_AUTO:
1792    case CAM_FOCUS_MODE_MACRO:
1793        {
1794            rc = mCameraHandle->ops->do_auto_focus(mCameraHandle->camera_handle);
1795            if (rc == NO_ERROR) {
1796                mParameters.setAFRunning(true);
1797            }
1798        }
1799        break;
1800    case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
1801        // According to Google API definition, the focus callback will immediately
1802        // return with a boolean that indicates whether the focus is sharp or not.
1803        // The focus position is locked after autoFocus call.
1804        // in this sense, the effect is the same as cancel_auto_focus
1805        {
1806            rc = mParameters.setLockCAF(true);
1807
1808            // send evt notify that foucs is done
1809            sendEvtNotify(CAMERA_MSG_FOCUS,
1810                          (m_currentFocusState == CAM_AF_FOCUSED)? true : false,
1811                          0);
1812        }
1813        break;
1814    case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
1815        // According to Google API definition, if the autofocus is in the middle
1816        // of scanning, the focus callback will return when it completes. If the
1817        // autofocus is not scanning, focus callback will immediately return with
1818        // a boolean that indicates whether the focus is sharp or not. The apps
1819        // can then decide if they want to take a picture immediately or to change
1820        // the focus mode to auto, and run a full autofocus cycle. The focus position
1821        // is locked after autoFocus call.
1822        if (m_currentFocusState != CAM_AF_SCANNING) {
1823            // lock focus
1824            rc = mParameters.setLockCAF(true);
1825
1826            // send evt notify that foucs is done
1827            sendEvtNotify(CAMERA_MSG_FOCUS,
1828                          (m_currentFocusState == CAM_AF_FOCUSED)? true : false,
1829                          0);
1830        } else {
1831            // set flag that lock CAF is needed once focus state becomes focsued/not focused
1832            mParameters.setLockCAFNeeded(true);
1833            rc = NO_ERROR;
1834        }
1835        break;
1836    case CAM_FOCUS_MODE_INFINITY:
1837    case CAM_FOCUS_MODE_FIXED:
1838    case CAM_FOCUS_MODE_EDOF:
1839    default:
1840        ALOGE("%s: No ops in focusMode (%d)", __func__, focusMode);
1841        rc = BAD_VALUE;
1842        break;
1843    }
1844    return rc;
1845}
1846
1847/*===========================================================================
1848 * FUNCTION   : cancelAutoFocus
1849 *
1850 * DESCRIPTION: cancel auto focus impl
1851 *
1852 * PARAMETERS : none
1853 *
1854 * RETURN     : int32_t type of status
1855 *              NO_ERROR  -- success
1856 *              none-zero failure code
1857 *==========================================================================*/
1858int QCamera2HardwareInterface::cancelAutoFocus()
1859{
1860    int rc = NO_ERROR;
1861    cam_focus_mode_type focusMode = mParameters.getFocusMode();
1862
1863    switch (focusMode) {
1864    case CAM_FOCUS_MODE_AUTO:
1865    case CAM_FOCUS_MODE_MACRO:
1866        if (mParameters.isAFRunning()) {
1867            rc = mCameraHandle->ops->cancel_auto_focus(mCameraHandle->camera_handle);
1868            if (rc == NO_ERROR) {
1869                mParameters.setAFRunning(false);
1870            }
1871        }
1872        break;
1873    case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
1874    case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
1875        if (mParameters.isCAFLocked()) {
1876            // resume CAF by unlock CAF
1877            rc = mParameters.setLockCAF(false);;
1878            mParameters.setLockCAFNeeded(false);
1879        }
1880        break;
1881    case CAM_FOCUS_MODE_INFINITY:
1882    case CAM_FOCUS_MODE_FIXED:
1883    case CAM_FOCUS_MODE_EDOF:
1884    default:
1885        ALOGI("%s: No ops in focusMode (%d)", __func__, focusMode);
1886        break;
1887    }
1888    return rc;
1889}
1890
1891/*===========================================================================
1892 * FUNCTION   : takePicture
1893 *
1894 * DESCRIPTION: take picture impl
1895 *
1896 * PARAMETERS : none
1897 *
1898 * RETURN     : int32_t type of status
1899 *              NO_ERROR  -- success
1900 *              none-zero failure code
1901 *==========================================================================*/
1902int QCamera2HardwareInterface::takePicture()
1903{
1904    int rc = NO_ERROR;
1905    uint8_t numSnapshots = mParameters.getNumOfSnapshots();
1906    ALOGD("%s: E", __func__);
1907    if (mParameters.isZSLMode()) {
1908        QCameraPicChannel *pZSLChannel =
1909            (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
1910        if (NULL != pZSLChannel) {
1911            // start postprocessor
1912            m_postprocessor.start(pZSLChannel);
1913
1914            rc = pZSLChannel->takePicture(numSnapshots);
1915            if (rc != NO_ERROR) {
1916                ALOGE("%s: cannot take ZSL picture", __func__);
1917                m_postprocessor.stop();
1918                return rc;
1919            }
1920        } else {
1921            ALOGE("%s: ZSL channel is NULL", __func__);
1922            return UNKNOWN_ERROR;
1923        }
1924    } else {
1925        // normal capture case
1926        // need to stop preview channel
1927        stopChannel(QCAMERA_CH_TYPE_PREVIEW);
1928        delChannel(QCAMERA_CH_TYPE_PREVIEW);
1929
1930        // start snapshot
1931        if (mParameters.isJpegPictureFormat() ||
1932            mParameters.isNV16PictureFormat() ) {
1933            rc = addCaptureChannel();
1934            if (rc == NO_ERROR) {
1935                // start postprocessor
1936                m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_CAPTURE]);
1937
1938                // start catpure channel
1939                rc = startChannel(QCAMERA_CH_TYPE_CAPTURE);
1940                if (rc != NO_ERROR) {
1941                    ALOGE("%s: cannot start capture channel", __func__);
1942                    m_postprocessor.stop();
1943                    delChannel(QCAMERA_CH_TYPE_CAPTURE);
1944                    return rc;
1945                }
1946            } else {
1947                ALOGE("%s: cannot add capture channel", __func__);
1948                return rc;
1949            }
1950        } else {
1951            rc = addRawChannel();
1952            if (rc == NO_ERROR) {
1953                // start postprocessor
1954                m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]);
1955                rc = startChannel(QCAMERA_CH_TYPE_RAW);
1956                if (rc != NO_ERROR) {
1957                    ALOGE("%s: cannot start raw channel", __func__);
1958                    m_postprocessor.stop();
1959                    delChannel(QCAMERA_CH_TYPE_RAW);
1960                    return rc;
1961                }
1962            } else {
1963                ALOGE("%s: cannot add raw channel", __func__);
1964                return rc;
1965            }
1966        }
1967    }
1968    ALOGD("%s: X", __func__);
1969    return rc;
1970}
1971
1972/*===========================================================================
1973 * FUNCTION   : cancelPicture
1974 *
1975 * DESCRIPTION: cancel picture impl
1976 *
1977 * PARAMETERS : none
1978 *
1979 * RETURN     : int32_t type of status
1980 *              NO_ERROR  -- success
1981 *              none-zero failure code
1982 *==========================================================================*/
1983int QCamera2HardwareInterface::cancelPicture()
1984{
1985    //stop post processor
1986    m_postprocessor.stop();
1987
1988    if (mParameters.isZSLMode()) {
1989        QCameraPicChannel *pZSLChannel =
1990            (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
1991        if (NULL != pZSLChannel) {
1992            if (m_bStartZSLSnapshotCalled) {
1993                mCameraHandle->ops->stop_zsl_snapshot(
1994                        mCameraHandle->camera_handle);
1995                m_bStartZSLSnapshotCalled = false;
1996            }
1997            pZSLChannel->cancelPicture();
1998        }
1999    } else {
2000        // normal capture case
2001        if (mParameters.isJpegPictureFormat() ||
2002            mParameters.isNV16PictureFormat() ) {
2003            stopChannel(QCAMERA_CH_TYPE_CAPTURE);
2004            delChannel(QCAMERA_CH_TYPE_CAPTURE);
2005        } else {
2006            stopChannel(QCAMERA_CH_TYPE_RAW);
2007            delChannel(QCAMERA_CH_TYPE_RAW);
2008        }
2009    }
2010    return NO_ERROR;
2011}
2012
2013/*===========================================================================
2014 * FUNCTION   : takeLiveSnapshot
2015 *
2016 * DESCRIPTION: take live snapshot during recording
2017 *
2018 * PARAMETERS : none
2019 *
2020 * RETURN     : int32_t type of status
2021 *              NO_ERROR  -- success
2022 *              none-zero failure code
2023 *==========================================================================*/
2024int QCamera2HardwareInterface::takeLiveSnapshot()
2025{
2026    int rc = NO_ERROR;
2027
2028    // start post processor
2029    rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_SNAPSHOT]);
2030
2031    // start snapshot channel
2032    if (rc == NO_ERROR) {
2033        rc = startChannel(QCAMERA_CH_TYPE_SNAPSHOT);
2034    }
2035    return rc;
2036}
2037
2038/*===========================================================================
2039 * FUNCTION   : cancelLiveSnapshot
2040 *
2041 * DESCRIPTION: cancel current live snapshot request
2042 *
2043 * PARAMETERS : none
2044 *
2045 * RETURN     : int32_t type of status
2046 *              NO_ERROR  -- success
2047 *              none-zero failure code
2048 *==========================================================================*/
2049int QCamera2HardwareInterface::cancelLiveSnapshot()
2050{
2051    int rc = NO_ERROR;
2052
2053    //stop post processor
2054    m_postprocessor.stop();
2055
2056    // stop snapshot channel
2057    rc = stopChannel(QCAMERA_CH_TYPE_SNAPSHOT);
2058
2059    return rc;
2060}
2061
2062/*===========================================================================
2063 * FUNCTION   : getParameters
2064 *
2065 * DESCRIPTION: get parameters impl
2066 *
2067 * PARAMETERS : none
2068 *
2069 * RETURN     : a string containing parameter pairs
2070 *==========================================================================*/
2071char* QCamera2HardwareInterface::getParameters()
2072{
2073    char* strParams = NULL;
2074    String8 str;
2075    str = mParameters.flatten( );
2076    strParams = (char *)malloc(sizeof(char)*(str.length()+1));
2077    if(strParams != NULL){
2078        memset(strParams, 0, sizeof(char)*(str.length()+1));
2079        strncpy(strParams, str.string(), str.length());
2080        strParams[str.length()] = 0;
2081    }
2082    return strParams;
2083}
2084
2085/*===========================================================================
2086 * FUNCTION   : putParameters
2087 *
2088 * DESCRIPTION: put parameters string impl
2089 *
2090 * PARAMETERS :
2091 *   @parms   : parameters string to be released
2092 *
2093 * RETURN     : int32_t type of status
2094 *              NO_ERROR  -- success
2095 *              none-zero failure code
2096 *==========================================================================*/
2097int QCamera2HardwareInterface::putParameters(char *parms)
2098{
2099    free(parms);
2100    return NO_ERROR;
2101}
2102
2103/*===========================================================================
2104 * FUNCTION   : sendCommand
2105 *
2106 * DESCRIPTION: send command impl
2107 *
2108 * PARAMETERS :
2109 *   @command : command to be executed
2110 *   @arg1    : optional argument 1
2111 *   @arg2    : optional argument 2
2112 *
2113 * RETURN     : int32_t type of status
2114 *              NO_ERROR  -- success
2115 *              none-zero failure code
2116 *==========================================================================*/
2117int QCamera2HardwareInterface::sendCommand(int32_t command, int32_t /*arg1*/, int32_t /*arg2*/)
2118{
2119    int rc = NO_ERROR;
2120
2121    switch (command) {
2122    case CAMERA_CMD_START_FACE_DETECTION:
2123    case CAMERA_CMD_STOP_FACE_DETECTION:
2124        rc = setFaceDetection(command == CAMERA_CMD_START_FACE_DETECTION? true : false);
2125        break;
2126    default:
2127        rc = NO_ERROR;
2128        break;
2129    }
2130    return rc;
2131}
2132
2133/*===========================================================================
2134 * FUNCTION   : registerFaceImage
2135 *
2136 * DESCRIPTION: register face image impl
2137 *
2138 * PARAMETERS :
2139 *   @img_ptr : ptr to image buffer
2140 *   @config  : ptr to config struct about input image info
2141 *   @faceID  : [OUT] face ID to uniquely identifiy the registered face image
2142 *
2143 * RETURN     : int32_t type of status
2144 *              NO_ERROR  -- success
2145 *              none-zero failure code
2146 *==========================================================================*/
2147int QCamera2HardwareInterface::registerFaceImage(void *img_ptr,
2148                                                 cam_pp_offline_src_config_t *config,
2149                                                 int32_t &faceID)
2150{
2151    int rc = NO_ERROR;
2152    faceID = -1;
2153
2154    if (img_ptr == NULL || config == NULL) {
2155        ALOGE("%s: img_ptr or config is NULL", __func__);
2156        return BAD_VALUE;
2157    }
2158
2159    // allocate ion memory for source image
2160    QCameraHeapMemory *imgBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
2161    if (imgBuf == NULL) {
2162        ALOGE("%s: Unable to new heap memory obj for image buf", __func__);
2163        return NO_MEMORY;
2164    }
2165
2166    rc = imgBuf->allocate(1, config->input_buf_planes.plane_info.frame_len);
2167    if (rc < 0) {
2168        ALOGE("%s: Unable to allocate heap memory for image buf", __func__);
2169        delete imgBuf;
2170        return NO_MEMORY;
2171    }
2172
2173    void *pBufPtr = imgBuf->getPtr(0);
2174    if (pBufPtr == NULL) {
2175        ALOGE("%s: image buf is NULL", __func__);
2176        imgBuf->deallocate();
2177        delete imgBuf;
2178        return NO_MEMORY;
2179    }
2180    memcpy(pBufPtr, img_ptr, config->input_buf_planes.plane_info.frame_len);
2181
2182    cam_pp_feature_config_t pp_feature;
2183    memset(&pp_feature, 0, sizeof(cam_pp_feature_config_t));
2184    pp_feature.feature_mask = CAM_QCOM_FEATURE_REGISTER_FACE;
2185    QCameraReprocessChannel *pChannel =
2186        addOfflineReprocChannel(*config, pp_feature, NULL, NULL);
2187
2188    if (pChannel == NULL) {
2189        ALOGE("%s: fail to add offline reprocess channel", __func__);
2190        imgBuf->deallocate();
2191        delete imgBuf;
2192        return UNKNOWN_ERROR;
2193    }
2194
2195    rc = pChannel->start();
2196    if (rc != NO_ERROR) {
2197        ALOGE("%s: Cannot start reprocess channel", __func__);
2198        imgBuf->deallocate();
2199        delete imgBuf;
2200        delete pChannel;
2201        return rc;
2202    }
2203
2204    rc = pChannel->doReprocess(imgBuf->getFd(0), imgBuf->getSize(0), faceID);
2205
2206    // done with register face image, free imgbuf and delete reprocess channel
2207    imgBuf->deallocate();
2208    delete imgBuf;
2209    imgBuf = NULL;
2210    pChannel->stop();
2211    delete pChannel;
2212    pChannel = NULL;
2213
2214    return rc;
2215}
2216
2217/*===========================================================================
2218 * FUNCTION   : release
2219 *
2220 * DESCRIPTION: release camera resource impl
2221 *
2222 * PARAMETERS : none
2223 *
2224 * RETURN     : int32_t type of status
2225 *              NO_ERROR  -- success
2226 *              none-zero failure code
2227 *==========================================================================*/
2228int QCamera2HardwareInterface::release()
2229{
2230    // stop and delete all channels
2231    for (int i = 0; i <QCAMERA_CH_TYPE_MAX ; i++) {
2232        if (m_channels[i] != NULL) {
2233            stopChannel((qcamera_ch_type_enum_t)i);
2234            delChannel((qcamera_ch_type_enum_t)i);
2235        }
2236    }
2237
2238    return NO_ERROR;
2239}
2240
2241/*===========================================================================
2242 * FUNCTION   : dump
2243 *
2244 * DESCRIPTION: camera status dump impl
2245 *
2246 * PARAMETERS :
2247 *   @fd      : fd for the buffer to be dumped with camera status
2248 *
2249 * RETURN     : int32_t type of status
2250 *              NO_ERROR  -- success
2251 *              none-zero failure code
2252 *==========================================================================*/
2253int QCamera2HardwareInterface::dump(int /*fd*/)
2254{
2255    ALOGE("%s: not supported yet", __func__);
2256    return INVALID_OPERATION;
2257}
2258
2259/*===========================================================================
2260 * FUNCTION   : processAPI
2261 *
2262 * DESCRIPTION: process API calls from upper layer
2263 *
2264 * PARAMETERS :
2265 *   @api         : API to be processed
2266 *   @api_payload : ptr to API payload if any
2267 *
2268 * RETURN     : int32_t type of status
2269 *              NO_ERROR  -- success
2270 *              none-zero failure code
2271 *==========================================================================*/
2272int QCamera2HardwareInterface::processAPI(qcamera_sm_evt_enum_t api, void *api_payload)
2273{
2274    return m_stateMachine.procAPI(api, api_payload);
2275}
2276
2277/*===========================================================================
2278 * FUNCTION   : processEvt
2279 *
2280 * DESCRIPTION: process Evt from backend via mm-camera-interface
2281 *
2282 * PARAMETERS :
2283 *   @evt         : event type to be processed
2284 *   @evt_payload : ptr to event payload if any
2285 *
2286 * RETURN     : int32_t type of status
2287 *              NO_ERROR  -- success
2288 *              none-zero failure code
2289 *==========================================================================*/
2290int QCamera2HardwareInterface::processEvt(qcamera_sm_evt_enum_t evt, void *evt_payload)
2291{
2292    return m_stateMachine.procEvt(evt, evt_payload);
2293}
2294
2295/*===========================================================================
2296 * FUNCTION   : processSyncEvt
2297 *
2298 * DESCRIPTION: process synchronous Evt from backend
2299 *
2300 * PARAMETERS :
2301 *   @evt         : event type to be processed
2302 *   @evt_payload : ptr to event payload if any
2303 *
2304 * RETURN     : int32_t type of status
2305 *              NO_ERROR  -- success
2306 *              none-zero failure code
2307 *==========================================================================*/
2308int QCamera2HardwareInterface::processSyncEvt(qcamera_sm_evt_enum_t evt, void *evt_payload)
2309{
2310    int rc = NO_ERROR;
2311
2312    pthread_mutex_lock(&m_evtLock);
2313    rc =  processEvt(evt, evt_payload);
2314    if (rc == NO_ERROR) {
2315        memset(&m_evtResult, 0, sizeof(qcamera_api_result_t));
2316        while (m_evtResult.request_api != evt) {
2317            pthread_cond_wait(&m_evtCond, &m_evtLock);
2318        }
2319        rc =  m_evtResult.status;
2320    }
2321    pthread_mutex_unlock(&m_evtLock);
2322
2323    return rc;
2324}
2325
2326/*===========================================================================
2327 * FUNCTION   : evtHandle
2328 *
2329 * DESCRIPTION: Function registerd to mm-camera-interface to handle backend events
2330 *
2331 * PARAMETERS :
2332 *   @camera_handle : event type to be processed
2333 *   @evt           : ptr to event
2334 *   @user_data     : user data ptr
2335 *
2336 * RETURN     : none
2337 *==========================================================================*/
2338void QCamera2HardwareInterface::camEvtHandle(uint32_t /*camera_handle*/,
2339                                          mm_camera_event_t *evt,
2340                                          void *user_data)
2341{
2342    QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)user_data;
2343    if (obj && evt) {
2344        mm_camera_event_t *payload =
2345            (mm_camera_event_t *)malloc(sizeof(mm_camera_event_t));
2346        if (NULL != payload) {
2347            *payload = *evt;
2348            obj->processEvt(QCAMERA_SM_EVT_EVT_NOTIFY, payload);
2349        }
2350    } else {
2351        ALOGE("%s: NULL user_data", __func__);
2352    }
2353}
2354
2355/*===========================================================================
2356 * FUNCTION   : jpegEvtHandle
2357 *
2358 * DESCRIPTION: Function registerd to mm-jpeg-interface to handle jpeg events
2359 *
2360 * PARAMETERS :
2361 *   @status    : status of jpeg job
2362 *   @client_hdl: jpeg client handle
2363 *   @jobId     : jpeg job Id
2364 *   @p_ouput   : ptr to jpeg output result struct
2365 *   @userdata  : user data ptr
2366 *
2367 * RETURN     : none
2368 *==========================================================================*/
2369void QCamera2HardwareInterface::jpegEvtHandle(jpeg_job_status_t status,
2370                                              uint32_t /*client_hdl*/,
2371                                              uint32_t jobId,
2372                                              mm_jpeg_output_t *p_output,
2373                                              void *userdata)
2374{
2375    QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)userdata;
2376    if (obj) {
2377        qcamera_jpeg_evt_payload_t *payload =
2378            (qcamera_jpeg_evt_payload_t *)malloc(sizeof(qcamera_jpeg_evt_payload_t));
2379        if (NULL != payload) {
2380            memset(payload, 0, sizeof(qcamera_jpeg_evt_payload_t));
2381            payload->status = status;
2382            payload->jobId = jobId;
2383            if (p_output != NULL) {
2384                payload->out_data = *p_output;
2385            }
2386            obj->processEvt(QCAMERA_SM_EVT_JPEG_EVT_NOTIFY, payload);
2387        }
2388    } else {
2389        ALOGE("%s: NULL user_data", __func__);
2390    }
2391}
2392
2393/*===========================================================================
2394 * FUNCTION   : thermalEvtHandle
2395 *
2396 * DESCRIPTION: routine to handle thermal event notification
2397 *
2398 * PARAMETERS :
2399 *   @level      : thermal level
2400 *   @userdata   : userdata passed in during registration
2401 *   @data       : opaque data from thermal client
2402 *
2403 * RETURN     : int32_t type of status
2404 *              NO_ERROR  -- success
2405 *              none-zero failure code
2406 *==========================================================================*/
2407int QCamera2HardwareInterface::thermalEvtHandle(
2408        qcamera_thermal_level_enum_t level, void *userdata, void *data)
2409{
2410    // Make sure thermal events are logged
2411    ALOGI("%s: level = %d, userdata = %p, data = %p",
2412        __func__, level, userdata, data);
2413    //We don't need to lockAPI, waitAPI here. QCAMERA_SM_EVT_THERMAL_NOTIFY
2414    // becomes an aync call. This also means we can only pass payload
2415    // by value, not by address.
2416    return processAPI(QCAMERA_SM_EVT_THERMAL_NOTIFY, (void *)level);
2417}
2418
2419/*===========================================================================
2420 * FUNCTION   : sendEvtNotify
2421 *
2422 * DESCRIPTION: send event notify to notify thread
2423 *
2424 * PARAMETERS :
2425 *   @msg_type: msg type to be sent
2426 *   @ext1    : optional extension1
2427 *   @ext2    : optional extension2
2428 *
2429 * RETURN     : int32_t type of status
2430 *              NO_ERROR  -- success
2431 *              none-zero failure code
2432 *==========================================================================*/
2433int32_t QCamera2HardwareInterface::sendEvtNotify(int32_t msg_type,
2434                                                 int32_t ext1,
2435                                                 int32_t ext2)
2436{
2437    qcamera_callback_argm_t cbArg;
2438    memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
2439    cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK;
2440    cbArg.msg_type = msg_type;
2441    cbArg.ext1 = ext1;
2442    cbArg.ext2 = ext2;
2443    return m_cbNotifier.notifyCallback(cbArg);
2444}
2445
2446/*===========================================================================
2447 * FUNCTION   : processAutoFocusEvent
2448 *
2449 * DESCRIPTION: process auto focus event
2450 *
2451 * PARAMETERS :
2452 *   @focus_data: struct containing auto focus result info
2453 *
2454 * RETURN     : int32_t type of status
2455 *              NO_ERROR  -- success
2456 *              none-zero failure code
2457 *==========================================================================*/
2458int32_t QCamera2HardwareInterface::processAutoFocusEvent(cam_auto_focus_data_t &focus_data)
2459{
2460    int32_t ret = NO_ERROR;
2461
2462    m_currentFocusState = focus_data.focus_state;
2463
2464    cam_focus_mode_type focusMode = mParameters.getFocusMode();
2465    switch (focusMode) {
2466    case CAM_FOCUS_MODE_AUTO:
2467    case CAM_FOCUS_MODE_MACRO:
2468        if (mParameters.isAFRunning()) {
2469            if (focus_data.focus_state == CAM_AF_SCANNING) {
2470                // in the middle of focusing, just ignore it
2471                break;
2472            }
2473
2474            // update focus distance
2475            mParameters.updateFocusDistances(&focus_data.focus_dist);
2476            ret = sendEvtNotify(CAMERA_MSG_FOCUS,
2477                                (focus_data.focus_state == CAM_AF_FOCUSED)? true : false,
2478                                0);
2479            mParameters.setAFRunning(false);
2480        } else {
2481            ret = UNKNOWN_ERROR;
2482            ALOGE("%s: autoFocusEvent when no auto_focus running", __func__);
2483        }
2484        break;
2485    case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
2486    case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
2487        if (focus_data.focus_state == CAM_AF_FOCUSED ||
2488            focus_data.focus_state == CAM_AF_NOT_FOCUSED) {
2489            // update focus distance
2490            mParameters.updateFocusDistances(&focus_data.focus_dist);
2491            if (mParameters.isLockCAFNeeded()) {
2492                mParameters.setLockCAFNeeded(false);
2493                ret = mParameters.setLockCAF(true);
2494            }
2495
2496            ret = sendEvtNotify(CAMERA_MSG_FOCUS,
2497                  (focus_data.focus_state == CAM_AF_FOCUSED)? true : false,
2498                  0);
2499        }
2500        ret = sendEvtNotify(CAMERA_MSG_FOCUS_MOVE,
2501                (focus_data.focus_state == CAM_AF_SCANNING)? true : false,
2502                0);
2503        break;
2504    case CAM_FOCUS_MODE_INFINITY:
2505    case CAM_FOCUS_MODE_FIXED:
2506    case CAM_FOCUS_MODE_EDOF:
2507    default:
2508        ALOGD("%s: no ops for autofocus event in focusmode %d", __func__, focusMode);
2509        break;
2510    }
2511
2512    return ret;
2513}
2514
2515/*===========================================================================
2516 * FUNCTION   : processZoomEvent
2517 *
2518 * DESCRIPTION: process zoom event
2519 *
2520 * PARAMETERS :
2521 *   @crop_info : crop info as a result of zoom operation
2522 *
2523 * RETURN     : int32_t type of status
2524 *              NO_ERROR  -- success
2525 *              none-zero failure code
2526 *==========================================================================*/
2527int32_t QCamera2HardwareInterface::processZoomEvent(cam_crop_data_t &crop_info)
2528{
2529    int32_t ret = NO_ERROR;
2530
2531    for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
2532        if (m_channels[i] != NULL) {
2533            ret = m_channels[i]->processZoomDone(mPreviewWindow, crop_info);
2534        }
2535    }
2536    return ret;
2537}
2538
2539/*===========================================================================
2540 * FUNCTION   : processPrepSnapshotDone
2541 *
2542 * DESCRIPTION: process prep snapshot done event
2543 *
2544 * PARAMETERS :
2545 *   @prep_snapshot_state  : state of prepare snapshot done. In other words,
2546 *                           i.e. whether need future frames for capture.
2547 *
2548 * RETURN     : int32_t type of status
2549 *              NO_ERROR  -- success
2550 *              none-zero failure code
2551 *==========================================================================*/
2552int32_t QCamera2HardwareInterface::processPrepSnapshotDoneEvent(
2553                        cam_prep_snapshot_state_t prep_snapshot_state)
2554{
2555    int32_t ret = NO_ERROR;
2556
2557    if (m_channels[QCAMERA_CH_TYPE_ZSL] &&
2558        prep_snapshot_state == NEED_FUTURE_FRAME) {
2559
2560        ret = mCameraHandle->ops->start_zsl_snapshot(
2561                            mCameraHandle->camera_handle);
2562        if (ret < 0) {
2563            ALOGE("%s: start_led_zsl_capture failed %d",
2564                            __func__, ret);
2565            return ret;
2566        }
2567        m_bStartZSLSnapshotCalled = true;
2568    }
2569    return ret;
2570}
2571
2572/*===========================================================================
2573 * FUNCTION   : processJpegNotify
2574 *
2575 * DESCRIPTION: process jpeg event
2576 *
2577 * PARAMETERS :
2578 *   @jpeg_evt: ptr to jpeg event payload
2579 *
2580 * RETURN     : int32_t type of status
2581 *              NO_ERROR  -- success
2582 *              none-zero failure code
2583 *==========================================================================*/
2584int32_t QCamera2HardwareInterface::processJpegNotify(qcamera_jpeg_evt_payload_t *jpeg_evt)
2585{
2586    return m_postprocessor.processJpegEvt(jpeg_evt);
2587}
2588
2589/*===========================================================================
2590 * FUNCTION   : lockAPI
2591 *
2592 * DESCRIPTION: lock to process API
2593 *
2594 * PARAMETERS : none
2595 *
2596 * RETURN     : none
2597 *==========================================================================*/
2598void QCamera2HardwareInterface::lockAPI()
2599{
2600    pthread_mutex_lock(&m_lock);
2601}
2602
2603/*===========================================================================
2604 * FUNCTION   : waitAPIResult
2605 *
2606 * DESCRIPTION: wait for API result coming back. This is a blocking call, it will
2607 *              return only cerntain API event type arrives
2608 *
2609 * PARAMETERS :
2610 *   @api_evt : API event type
2611 *
2612 * RETURN     : none
2613 *==========================================================================*/
2614void QCamera2HardwareInterface::waitAPIResult(qcamera_sm_evt_enum_t api_evt)
2615{
2616    ALOGV("%s: wait for API result of evt (%d)", __func__, api_evt);
2617    memset(&m_apiResult, 0, sizeof(qcamera_api_result_t));
2618    while (m_apiResult.request_api != api_evt) {
2619        pthread_cond_wait(&m_cond, &m_lock);
2620    }
2621    ALOGV("%s: return (%d) from API result wait for evt (%d)",
2622          __func__, m_apiResult.status, api_evt);
2623}
2624
2625/*===========================================================================
2626 * FUNCTION   : unlockAPI
2627 *
2628 * DESCRIPTION: API processing is done, unlock
2629 *
2630 * PARAMETERS : none
2631 *
2632 * RETURN     : none
2633 *==========================================================================*/
2634void QCamera2HardwareInterface::unlockAPI()
2635{
2636    pthread_mutex_unlock(&m_lock);
2637}
2638
2639/*===========================================================================
2640 * FUNCTION   : signalAPIResult
2641 *
2642 * DESCRIPTION: signal condition viarable that cerntain API event type arrives
2643 *
2644 * PARAMETERS :
2645 *   @result  : API result
2646 *
2647 * RETURN     : none
2648 *==========================================================================*/
2649void QCamera2HardwareInterface::signalAPIResult(qcamera_api_result_t *result)
2650{
2651    pthread_mutex_lock(&m_lock);
2652    m_apiResult = *result;
2653    pthread_cond_signal(&m_cond);
2654    pthread_mutex_unlock(&m_lock);
2655}
2656
2657/*===========================================================================
2658 * FUNCTION   : signalEvtResult
2659 *
2660 * DESCRIPTION: signal condition variable that certain event was processed
2661 *
2662 * PARAMETERS :
2663 *   @result  : Event result
2664 *
2665 * RETURN     : none
2666 *==========================================================================*/
2667void QCamera2HardwareInterface::signalEvtResult(qcamera_api_result_t *result)
2668{
2669    pthread_mutex_lock(&m_evtLock);
2670    m_evtResult = *result;
2671    pthread_cond_signal(&m_evtCond);
2672    pthread_mutex_unlock(&m_evtLock);
2673}
2674
2675/*===========================================================================
2676 * FUNCTION   : addStreamToChannel
2677 *
2678 * DESCRIPTION: add a stream into a channel
2679 *
2680 * PARAMETERS :
2681 *   @pChannel   : ptr to channel obj
2682 *   @streamType : type of stream to be added
2683 *   @streamCB   : callback of stream
2684 *   @userData   : user data ptr to callback
2685 *
2686 * RETURN     : int32_t type of status
2687 *              NO_ERROR  -- success
2688 *              none-zero failure code
2689 *==========================================================================*/
2690int32_t QCamera2HardwareInterface::addStreamToChannel(QCameraChannel *pChannel,
2691                                                      cam_stream_type_t streamType,
2692                                                      stream_cb_routine streamCB,
2693                                                      void *userData)
2694{
2695    int32_t rc = NO_ERROR;
2696    QCameraHeapMemory *pStreamInfo = allocateStreamInfoBuf(streamType);
2697    if (pStreamInfo == NULL) {
2698        ALOGE("%s: no mem for stream info buf", __func__);
2699        return NO_MEMORY;
2700    }
2701    uint8_t minStreamBufNum = getBufNumRequired(streamType);
2702    rc = pChannel->addStream(*this,
2703                             pStreamInfo,
2704                             minStreamBufNum,
2705                             &gCamCapability[mCameraId]->padding_info,
2706                             streamCB, userData);
2707    if (rc != NO_ERROR) {
2708        ALOGE("%s: add stream type (%d) failed, ret = %d",
2709              __func__, streamType, rc);
2710        pStreamInfo->deallocate();
2711        delete pStreamInfo;
2712        return rc;
2713    }
2714
2715    return rc;
2716}
2717
2718/*===========================================================================
2719 * FUNCTION   : addPreviewChannel
2720 *
2721 * DESCRIPTION: add a preview channel that contains a preview stream
2722 *
2723 * PARAMETERS : none
2724 *
2725 * RETURN     : int32_t type of status
2726 *              NO_ERROR  -- success
2727 *              none-zero failure code
2728 *==========================================================================*/
2729int32_t QCamera2HardwareInterface::addPreviewChannel()
2730{
2731    int32_t rc = NO_ERROR;
2732    QCameraChannel *pChannel = NULL;
2733
2734    if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
2735        // if we had preview channel before, delete it first
2736        delete m_channels[QCAMERA_CH_TYPE_PREVIEW];
2737        m_channels[QCAMERA_CH_TYPE_PREVIEW] = NULL;
2738    }
2739
2740    pChannel = new QCameraChannel(mCameraHandle->camera_handle,
2741                                  mCameraHandle->ops);
2742    if (NULL == pChannel) {
2743        ALOGE("%s: no mem for preview channel", __func__);
2744        return NO_MEMORY;
2745    }
2746
2747    // preview only channel, don't need bundle attr and cb
2748    rc = pChannel->init(NULL, NULL, NULL);
2749    if (rc != NO_ERROR) {
2750        ALOGE("%s: init preview channel failed, ret = %d", __func__, rc);
2751        delete pChannel;
2752        return rc;
2753    }
2754
2755    // meta data stream always coexists with preview if applicable
2756    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
2757                            metadata_stream_cb_routine, this);
2758    if (rc != NO_ERROR) {
2759        ALOGE("%s: add metadata stream failed, ret = %d", __func__, rc);
2760        delete pChannel;
2761        return rc;
2762    }
2763
2764    if (isNoDisplayMode()) {
2765        rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
2766                                nodisplay_preview_stream_cb_routine, this);
2767    } else {
2768        rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
2769                                preview_stream_cb_routine, this);
2770    }
2771    if (rc != NO_ERROR) {
2772        ALOGE("%s: add preview stream failed, ret = %d", __func__, rc);
2773        delete pChannel;
2774        return rc;
2775    }
2776
2777    m_channels[QCAMERA_CH_TYPE_PREVIEW] = pChannel;
2778    return rc;
2779}
2780
2781/*===========================================================================
2782 * FUNCTION   : addVideoChannel
2783 *
2784 * DESCRIPTION: add a video channel that contains a video stream
2785 *
2786 * PARAMETERS : none
2787 *
2788 * RETURN     : int32_t type of status
2789 *              NO_ERROR  -- success
2790 *              none-zero failure code
2791 *==========================================================================*/
2792int32_t QCamera2HardwareInterface::addVideoChannel()
2793{
2794    int32_t rc = NO_ERROR;
2795    QCameraVideoChannel *pChannel = NULL;
2796
2797    if (m_channels[QCAMERA_CH_TYPE_VIDEO] != NULL) {
2798        // if we had video channel before, delete it first
2799        delete m_channels[QCAMERA_CH_TYPE_VIDEO];
2800        m_channels[QCAMERA_CH_TYPE_VIDEO] = NULL;
2801    }
2802
2803    pChannel = new QCameraVideoChannel(mCameraHandle->camera_handle,
2804                                       mCameraHandle->ops);
2805    if (NULL == pChannel) {
2806        ALOGE("%s: no mem for video channel", __func__);
2807        return NO_MEMORY;
2808    }
2809
2810    // preview only channel, don't need bundle attr and cb
2811    rc = pChannel->init(NULL, NULL, NULL);
2812    if (rc != 0) {
2813        ALOGE("%s: init video channel failed, ret = %d", __func__, rc);
2814        delete pChannel;
2815        return rc;
2816    }
2817
2818    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_VIDEO,
2819                            video_stream_cb_routine, this);
2820    if (rc != NO_ERROR) {
2821        ALOGE("%s: add video stream failed, ret = %d", __func__, rc);
2822        delete pChannel;
2823        return rc;
2824    }
2825
2826    m_channels[QCAMERA_CH_TYPE_VIDEO] = pChannel;
2827    return rc;
2828}
2829
2830/*===========================================================================
2831 * FUNCTION   : addSnapshotChannel
2832 *
2833 * DESCRIPTION: add a snapshot channel that contains a snapshot stream
2834 *
2835 * PARAMETERS : none
2836 *
2837 * RETURN     : int32_t type of status
2838 *              NO_ERROR  -- success
2839 *              none-zero failure code
2840 * NOTE       : Add this channel for live snapshot usecase. Regular capture will
2841 *              use addCaptureChannel.
2842 *==========================================================================*/
2843int32_t QCamera2HardwareInterface::addSnapshotChannel()
2844{
2845    int32_t rc = NO_ERROR;
2846    QCameraChannel *pChannel = NULL;
2847
2848    if (m_channels[QCAMERA_CH_TYPE_SNAPSHOT] != NULL) {
2849        // if we had ZSL channel before, delete it first
2850        delete m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
2851        m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = NULL;
2852    }
2853
2854    pChannel = new QCameraChannel(mCameraHandle->camera_handle,
2855                                  mCameraHandle->ops);
2856    if (NULL == pChannel) {
2857        ALOGE("%s: no mem for snapshot channel", __func__);
2858        return NO_MEMORY;
2859    }
2860
2861    rc = pChannel->init(NULL, NULL, NULL);
2862    if (rc != NO_ERROR) {
2863        ALOGE("%s: init snapshot channel failed, ret = %d", __func__, rc);
2864        delete pChannel;
2865        return rc;
2866    }
2867
2868    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
2869                            snapshot_stream_cb_routine, this);
2870    if (rc != NO_ERROR) {
2871        ALOGE("%s: add snapshot stream failed, ret = %d", __func__, rc);
2872        delete pChannel;
2873        return rc;
2874    }
2875
2876    m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = pChannel;
2877    return rc;
2878}
2879
2880/*===========================================================================
2881 * FUNCTION   : addRawChannel
2882 *
2883 * DESCRIPTION: add a raw channel that contains a raw image stream
2884 *
2885 * PARAMETERS : none
2886 *
2887 * RETURN     : int32_t type of status
2888 *              NO_ERROR  -- success
2889 *              none-zero failure code
2890 *==========================================================================*/
2891int32_t QCamera2HardwareInterface::addRawChannel()
2892{
2893    int32_t rc = NO_ERROR;
2894    QCameraChannel *pChannel = NULL;
2895
2896    if (m_channels[QCAMERA_CH_TYPE_RAW] != NULL) {
2897        // if we had raw channel before, delete it first
2898        delete m_channels[QCAMERA_CH_TYPE_RAW];
2899        m_channels[QCAMERA_CH_TYPE_RAW] = NULL;
2900    }
2901
2902    pChannel = new QCameraChannel(mCameraHandle->camera_handle,
2903                                  mCameraHandle->ops);
2904    if (NULL == pChannel) {
2905        ALOGE("%s: no mem for raw channel", __func__);
2906        return NO_MEMORY;
2907    }
2908
2909    rc = pChannel->init(NULL, NULL, NULL);
2910    if (rc != NO_ERROR) {
2911        ALOGE("%s: init raw channel failed, ret = %d", __func__, rc);
2912        delete pChannel;
2913        return rc;
2914    }
2915
2916    // meta data stream always coexists with snapshot in regular RAW capture case
2917    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
2918                            metadata_stream_cb_routine, this);
2919    if (rc != NO_ERROR) {
2920        ALOGE("%s: add metadata stream failed, ret = %d", __func__, rc);
2921        delete pChannel;
2922        return rc;
2923    }
2924
2925    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
2926                            raw_stream_cb_routine, this);
2927    if (rc != NO_ERROR) {
2928        ALOGE("%s: add snapshot stream failed, ret = %d", __func__, rc);
2929        delete pChannel;
2930        return rc;
2931    }
2932
2933    m_channels[QCAMERA_CH_TYPE_RAW] = pChannel;
2934    return rc;
2935}
2936
2937/*===========================================================================
2938 * FUNCTION   : addZSLChannel
2939 *
2940 * DESCRIPTION: add a ZSL channel that contains a preview stream and
2941 *              a snapshot stream
2942 *
2943 * PARAMETERS : none
2944 *
2945 * RETURN     : int32_t type of status
2946 *              NO_ERROR  -- success
2947 *              none-zero failure code
2948 *==========================================================================*/
2949int32_t QCamera2HardwareInterface::addZSLChannel()
2950{
2951    int32_t rc = NO_ERROR;
2952    QCameraPicChannel *pChannel = NULL;
2953
2954    if (m_channels[QCAMERA_CH_TYPE_ZSL] != NULL) {
2955        // if we had ZSL channel before, delete it first
2956        delete m_channels[QCAMERA_CH_TYPE_ZSL];
2957        m_channels[QCAMERA_CH_TYPE_ZSL] = NULL;
2958    }
2959
2960    pChannel = new QCameraPicChannel(mCameraHandle->camera_handle,
2961                                     mCameraHandle->ops);
2962    if (NULL == pChannel) {
2963        ALOGE("%s: no mem for ZSL channel", __func__);
2964        return NO_MEMORY;
2965    }
2966
2967    // ZSL channel, init with bundle attr and cb
2968    mm_camera_channel_attr_t attr;
2969    memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
2970    attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
2971    attr.look_back = mParameters.getZSLBackLookCount();
2972    attr.post_frame_skip = mParameters.getZSLBurstInterval();
2973    attr.water_mark = mParameters.getZSLQueueDepth();
2974    attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
2975    rc = pChannel->init(&attr,
2976                        zsl_channel_cb,
2977                        this);
2978    if (rc != 0) {
2979        ALOGE("%s: init ZSL channel failed, ret = %d", __func__, rc);
2980        delete pChannel;
2981        return rc;
2982    }
2983
2984    // meta data stream always coexists with preview if applicable
2985    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
2986                            metadata_stream_cb_routine, this);
2987    if (rc != NO_ERROR) {
2988        ALOGE("%s: add metadata stream failed, ret = %d", __func__, rc);
2989        delete pChannel;
2990        return rc;
2991    }
2992
2993    if (isNoDisplayMode()) {
2994        rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
2995                                nodisplay_preview_stream_cb_routine, this);
2996    } else {
2997        rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
2998                                preview_stream_cb_routine, this);
2999    }
3000    if (rc != NO_ERROR) {
3001        ALOGE("%s: add preview stream failed, ret = %d", __func__, rc);
3002        delete pChannel;
3003        return rc;
3004    }
3005
3006    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
3007                            NULL, this);
3008    if (rc != NO_ERROR) {
3009        ALOGE("%s: add snapshot stream failed, ret = %d", __func__, rc);
3010        delete pChannel;
3011        return rc;
3012    }
3013
3014    m_channels[QCAMERA_CH_TYPE_ZSL] = pChannel;
3015    return rc;
3016}
3017
3018/*===========================================================================
3019 * FUNCTION   : addCaptureChannel
3020 *
3021 * DESCRIPTION: add a capture channel that contains a snapshot stream
3022 *              and a postview stream
3023 *
3024 * PARAMETERS : none
3025 *
3026 * RETURN     : int32_t type of status
3027 *              NO_ERROR  -- success
3028 *              none-zero failure code
3029 * NOTE       : Add this channel for regular capture usecase.
3030 *              For Live snapshot usecase, use addSnapshotChannel.
3031 *==========================================================================*/
3032int32_t QCamera2HardwareInterface::addCaptureChannel()
3033{
3034    int32_t rc = NO_ERROR;
3035    QCameraChannel *pChannel = NULL;
3036
3037    if (m_channels[QCAMERA_CH_TYPE_CAPTURE] != NULL) {
3038        delete m_channels[QCAMERA_CH_TYPE_CAPTURE];
3039        m_channels[QCAMERA_CH_TYPE_CAPTURE] = NULL;
3040    }
3041
3042    pChannel = new QCameraChannel(mCameraHandle->camera_handle,
3043                                  mCameraHandle->ops);
3044    if (NULL == pChannel) {
3045        ALOGE("%s: no mem for capture channel", __func__);
3046        return NO_MEMORY;
3047    }
3048
3049    // Capture channel, only need snapshot and postview streams start together
3050    mm_camera_channel_attr_t attr;
3051    memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
3052    attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
3053    attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
3054
3055    rc = pChannel->init(&attr,
3056                        capture_channel_cb_routine,
3057                        this);
3058    if (rc != NO_ERROR) {
3059        ALOGE("%s: init capture channel failed, ret = %d", __func__, rc);
3060        delete pChannel;
3061        return rc;
3062    }
3063
3064
3065    // meta data stream always coexists with snapshot in regular capture case
3066    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
3067                            metadata_stream_cb_routine, this);
3068    if (rc != NO_ERROR) {
3069        ALOGE("%s: add metadata stream failed, ret = %d", __func__, rc);
3070        delete pChannel;
3071        return rc;
3072    }
3073
3074    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_POSTVIEW,
3075                            postview_stream_cb_routine, this);
3076
3077    if (rc != NO_ERROR) {
3078        ALOGE("%s: add postview stream failed, ret = %d", __func__, rc);
3079        delete pChannel;
3080        return rc;
3081    }
3082
3083    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
3084                            NULL, this);
3085    if (rc != NO_ERROR) {
3086        ALOGE("%s: add snapshot stream failed, ret = %d", __func__, rc);
3087        delete pChannel;
3088        return rc;
3089    }
3090
3091    m_channels[QCAMERA_CH_TYPE_CAPTURE] = pChannel;
3092    return rc;
3093}
3094
3095/*===========================================================================
3096 * FUNCTION   : addMetaDataChannel
3097 *
3098 * DESCRIPTION: add a meta data channel that contains a metadata stream
3099 *
3100 * PARAMETERS : none
3101 *
3102 * RETURN     : int32_t type of status
3103 *              NO_ERROR  -- success
3104 *              none-zero failure code
3105 *==========================================================================*/
3106int32_t QCamera2HardwareInterface::addMetaDataChannel()
3107{
3108    int32_t rc = NO_ERROR;
3109    QCameraChannel *pChannel = NULL;
3110
3111    if (m_channels[QCAMERA_CH_TYPE_METADATA] != NULL) {
3112        delete m_channels[QCAMERA_CH_TYPE_METADATA];
3113        m_channels[QCAMERA_CH_TYPE_METADATA] = NULL;
3114    }
3115
3116    pChannel = new QCameraChannel(mCameraHandle->camera_handle,
3117                                  mCameraHandle->ops);
3118    if (NULL == pChannel) {
3119        ALOGE("%s: no mem for metadata channel", __func__);
3120        return NO_MEMORY;
3121    }
3122
3123    rc = pChannel->init(NULL,
3124                        NULL,
3125                        NULL);
3126    if (rc != NO_ERROR) {
3127        ALOGE("%s: init metadata channel failed, ret = %d", __func__, rc);
3128        delete pChannel;
3129        return rc;
3130    }
3131
3132    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
3133                            metadata_stream_cb_routine, this);
3134    if (rc != NO_ERROR) {
3135        ALOGE("%s: add metadata stream failed, ret = %d", __func__, rc);
3136        delete pChannel;
3137        return rc;
3138    }
3139
3140    m_channels[QCAMERA_CH_TYPE_METADATA] = pChannel;
3141    return rc;
3142}
3143
3144/*===========================================================================
3145 * FUNCTION   : addOnlineReprocChannel
3146 *
3147 * DESCRIPTION: add a online reprocess channel that will do reprocess on frames
3148 *              coming from input channel
3149 *
3150 * PARAMETERS :
3151 *   @pInputChannel : ptr to input channel whose frames will be post-processed
3152 *
3153 * RETURN     : Ptr to the newly created channel obj. NULL if failed.
3154 *==========================================================================*/
3155QCameraReprocessChannel *QCamera2HardwareInterface::addOnlineReprocChannel(
3156                                                      QCameraChannel *pInputChannel)
3157{
3158    int32_t rc = NO_ERROR;
3159    QCameraReprocessChannel *pChannel = NULL;
3160
3161    if (pInputChannel == NULL) {
3162        ALOGE("%s: input channel obj is NULL", __func__);
3163        return NULL;
3164    }
3165
3166    pChannel = new QCameraReprocessChannel(mCameraHandle->camera_handle,
3167                                           mCameraHandle->ops);
3168    if (NULL == pChannel) {
3169        ALOGE("%s: no mem for reprocess channel", __func__);
3170        return NULL;
3171    }
3172
3173    // Capture channel, only need snapshot and postview streams start together
3174    mm_camera_channel_attr_t attr;
3175    memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
3176    attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
3177    attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
3178    rc = pChannel->init(&attr,
3179                        postproc_channel_cb_routine,
3180                        this);
3181    if (rc != NO_ERROR) {
3182        ALOGE("%s: init reprocess channel failed, ret = %d", __func__, rc);
3183        delete pChannel;
3184        return NULL;
3185    }
3186
3187    // pp feature config
3188    cam_pp_feature_config_t pp_config;
3189    memset(&pp_config, 0, sizeof(cam_pp_feature_config_t));
3190    if (gCamCapability[mCameraId]->min_required_pp_mask & CAM_QCOM_FEATURE_SHARPNESS) {
3191        pp_config.feature_mask |= CAM_QCOM_FEATURE_SHARPNESS;
3192        pp_config.sharpness = mParameters.getInt(QCameraParameters::KEY_QC_SHARPNESS);
3193    }
3194
3195    if (mParameters.isWNREnabled()) {
3196        pp_config.feature_mask |= CAM_QCOM_FEATURE_DENOISE2D;
3197        pp_config.denoise2d.denoise_enable = 1;
3198        pp_config.denoise2d.process_plates = mParameters.getWaveletDenoiseProcessPlate();
3199    }
3200
3201    if (isCACEnabled()) {
3202        pp_config.feature_mask |= CAM_QCOM_FEATURE_CAC;
3203    }
3204
3205    if (needRotationReprocess()) {
3206        pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION;
3207        int rotation = mParameters.getJpegRotation();
3208        if (rotation == 0) {
3209            pp_config.rotation = ROTATE_0;
3210        } else if (rotation == 90) {
3211            pp_config.rotation = ROTATE_90;
3212        } else if (rotation == 180) {
3213            pp_config.rotation = ROTATE_180;
3214        } else if (rotation == 270) {
3215            pp_config.rotation = ROTATE_270;
3216        }
3217    }
3218
3219    uint8_t minStreamBufNum = mParameters.getNumOfSnapshots();
3220    rc = pChannel->addReprocStreamsFromSource(*this,
3221                                              pp_config,
3222                                              pInputChannel,
3223                                              minStreamBufNum,
3224                                              &gCamCapability[mCameraId]->padding_info);
3225    if (rc != NO_ERROR) {
3226        delete pChannel;
3227        return NULL;
3228    }
3229
3230    return pChannel;
3231}
3232
3233/*===========================================================================
3234 * FUNCTION   : addOfflineReprocChannel
3235 *
3236 * DESCRIPTION: add a offline reprocess channel contains one reproc stream,
3237 *              that will do reprocess on frames coming from external images
3238 *
3239 * PARAMETERS :
3240 *   @img_config  : offline reporcess image info
3241 *   @pp_feature  : pp feature config
3242 *
3243 * RETURN     : int32_t type of status
3244 *              NO_ERROR  -- success
3245 *              none-zero failure code
3246 *==========================================================================*/
3247QCameraReprocessChannel *QCamera2HardwareInterface::addOfflineReprocChannel(
3248                                            cam_pp_offline_src_config_t &img_config,
3249                                            cam_pp_feature_config_t &pp_feature,
3250                                            stream_cb_routine stream_cb,
3251                                            void *userdata)
3252{
3253    int32_t rc = NO_ERROR;
3254    QCameraReprocessChannel *pChannel = NULL;
3255
3256    pChannel = new QCameraReprocessChannel(mCameraHandle->camera_handle,
3257                                           mCameraHandle->ops);
3258    if (NULL == pChannel) {
3259        ALOGE("%s: no mem for reprocess channel", __func__);
3260        return NULL;
3261    }
3262
3263    rc = pChannel->init(NULL, NULL, NULL);
3264    if (rc != NO_ERROR) {
3265        ALOGE("%s: init reprocess channel failed, ret = %d", __func__, rc);
3266        delete pChannel;
3267        return NULL;
3268    }
3269
3270    QCameraHeapMemory *pStreamInfo = allocateStreamInfoBuf(CAM_STREAM_TYPE_OFFLINE_PROC);
3271    if (pStreamInfo == NULL) {
3272        ALOGE("%s: no mem for stream info buf", __func__);
3273        delete pChannel;
3274        return NULL;
3275    }
3276
3277    cam_stream_info_t *streamInfoBuf = (cam_stream_info_t *)pStreamInfo->getPtr(0);
3278    memset(streamInfoBuf, 0, sizeof(cam_stream_info_t));
3279    streamInfoBuf->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC;
3280    streamInfoBuf->fmt = img_config.input_fmt;
3281    streamInfoBuf->dim = img_config.input_dim;
3282    streamInfoBuf->buf_planes = img_config.input_buf_planes;
3283    streamInfoBuf->streaming_mode = CAM_STREAMING_MODE_BURST;
3284    streamInfoBuf->num_of_burst = img_config.num_of_bufs;
3285
3286    streamInfoBuf->reprocess_config.pp_type = CAM_OFFLINE_REPROCESS_TYPE;
3287    streamInfoBuf->reprocess_config.offline = img_config;
3288    streamInfoBuf->reprocess_config.pp_feature_config = pp_feature;
3289
3290    rc = pChannel->addStream(*this,
3291                             pStreamInfo, img_config.num_of_bufs,
3292                             &gCamCapability[mCameraId]->padding_info,
3293                             stream_cb, userdata);
3294
3295    if (rc != NO_ERROR) {
3296        ALOGE("%s: add reprocess stream failed, ret = %d", __func__, rc);
3297        pStreamInfo->deallocate();
3298        delete pStreamInfo;
3299        delete pChannel;
3300        return NULL;
3301    }
3302
3303    return pChannel;
3304}
3305
3306/*===========================================================================
3307 * FUNCTION   : addChannel
3308 *
3309 * DESCRIPTION: add a channel by its type
3310 *
3311 * PARAMETERS :
3312 *   @ch_type : channel type
3313 *
3314 * RETURN     : int32_t type of status
3315 *              NO_ERROR  -- success
3316 *              none-zero failure code
3317 *==========================================================================*/
3318int32_t QCamera2HardwareInterface::addChannel(qcamera_ch_type_enum_t ch_type)
3319{
3320    int32_t rc = UNKNOWN_ERROR;
3321    switch (ch_type) {
3322    case QCAMERA_CH_TYPE_ZSL:
3323        rc = addZSLChannel();
3324        break;
3325    case QCAMERA_CH_TYPE_CAPTURE:
3326        rc = addCaptureChannel();
3327        break;
3328    case QCAMERA_CH_TYPE_PREVIEW:
3329        rc = addPreviewChannel();
3330        break;
3331    case QCAMERA_CH_TYPE_VIDEO:
3332        rc = addVideoChannel();
3333        break;
3334    case QCAMERA_CH_TYPE_SNAPSHOT:
3335        rc = addSnapshotChannel();
3336        break;
3337    case QCAMERA_CH_TYPE_RAW:
3338        rc = addRawChannel();
3339        break;
3340    case QCAMERA_CH_TYPE_METADATA:
3341        rc = addMetaDataChannel();
3342        break;
3343    default:
3344        break;
3345    }
3346    return rc;
3347}
3348
3349/*===========================================================================
3350 * FUNCTION   : delChannel
3351 *
3352 * DESCRIPTION: delete a channel by its type
3353 *
3354 * PARAMETERS :
3355 *   @ch_type : channel type
3356 *
3357 * RETURN     : int32_t type of status
3358 *              NO_ERROR  -- success
3359 *              none-zero failure code
3360 *==========================================================================*/
3361int32_t QCamera2HardwareInterface::delChannel(qcamera_ch_type_enum_t ch_type)
3362{
3363    if (m_channels[ch_type] != NULL) {
3364        delete m_channels[ch_type];
3365        m_channels[ch_type] = NULL;
3366    }
3367
3368    return NO_ERROR;
3369}
3370
3371/*===========================================================================
3372 * FUNCTION   : startChannel
3373 *
3374 * DESCRIPTION: start a channel by its type
3375 *
3376 * PARAMETERS :
3377 *   @ch_type : channel type
3378 *
3379 * RETURN     : int32_t type of status
3380 *              NO_ERROR  -- success
3381 *              none-zero failure code
3382 *==========================================================================*/
3383int32_t QCamera2HardwareInterface::startChannel(qcamera_ch_type_enum_t ch_type)
3384{
3385    int32_t rc = UNKNOWN_ERROR;
3386    if (m_channels[ch_type] != NULL) {
3387        rc = m_channels[ch_type]->start();
3388    }
3389
3390    return rc;
3391}
3392
3393/*===========================================================================
3394 * FUNCTION   : stopChannel
3395 *
3396 * DESCRIPTION: stop a channel by its type
3397 *
3398 * PARAMETERS :
3399 *   @ch_type : channel type
3400 *
3401 * RETURN     : int32_t type of status
3402 *              NO_ERROR  -- success
3403 *              none-zero failure code
3404 *==========================================================================*/
3405int32_t QCamera2HardwareInterface::stopChannel(qcamera_ch_type_enum_t ch_type)
3406{
3407    int32_t rc = UNKNOWN_ERROR;
3408    if (m_channels[ch_type] != NULL) {
3409        rc = m_channels[ch_type]->stop();
3410    }
3411
3412    return rc;
3413}
3414
3415/*===========================================================================
3416 * FUNCTION   : preparePreview
3417 *
3418 * DESCRIPTION: add channels needed for preview
3419 *
3420 * PARAMETERS : none
3421 *
3422 * RETURN     : int32_t type of status
3423 *              NO_ERROR  -- success
3424 *              none-zero failure code
3425 *==========================================================================*/
3426int32_t QCamera2HardwareInterface::preparePreview()
3427{
3428    int32_t rc = NO_ERROR;
3429
3430    if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() !=true) {
3431        rc = addChannel(QCAMERA_CH_TYPE_ZSL);
3432        if (rc != NO_ERROR) {
3433            return rc;
3434        }
3435    } else {
3436        bool recordingHint = mParameters.getRecordingHintValue();
3437        if(recordingHint) {
3438            rc = addChannel(QCAMERA_CH_TYPE_SNAPSHOT);
3439            if (rc != NO_ERROR) {
3440                return rc;
3441            }
3442
3443            rc = addChannel(QCAMERA_CH_TYPE_VIDEO);
3444            if (rc != NO_ERROR) {
3445                delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
3446                return rc;
3447            }
3448        }
3449
3450        rc = addChannel(QCAMERA_CH_TYPE_PREVIEW);
3451        if (rc != NO_ERROR) {
3452            if (recordingHint) {
3453                delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
3454                delChannel(QCAMERA_CH_TYPE_VIDEO);
3455            }
3456            return rc;
3457        }
3458
3459    }
3460
3461    return rc;
3462}
3463
3464/*===========================================================================
3465 * FUNCTION   : unpreparePreview
3466 *
3467 * DESCRIPTION: delete channels for preview
3468 *
3469 * PARAMETERS : none
3470 *
3471 * RETURN     : none
3472 *==========================================================================*/
3473void QCamera2HardwareInterface::unpreparePreview()
3474{
3475    if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() !=true) {
3476        delChannel(QCAMERA_CH_TYPE_ZSL);
3477    } else {
3478        delChannel(QCAMERA_CH_TYPE_PREVIEW);
3479        if(mParameters.getRecordingHintValue() == true) {
3480            delChannel(QCAMERA_CH_TYPE_VIDEO);
3481            delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
3482        }
3483    }
3484}
3485
3486/*===========================================================================
3487 * FUNCTION   : playShutter
3488 *
3489 * DESCRIPTION: send request to play shutter sound
3490 *
3491 * PARAMETERS : none
3492 *
3493 * RETURN     : none
3494 *==========================================================================*/
3495void QCamera2HardwareInterface::playShutter(){
3496     if (mNotifyCb == NULL ||
3497         msgTypeEnabledWithLock(CAMERA_MSG_SHUTTER) == 0){
3498         ALOGV("%s: shutter msg not enabled or NULL cb", __func__);
3499         return;
3500     }
3501
3502     qcamera_callback_argm_t cbArg;
3503     memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
3504     cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK;
3505     cbArg.msg_type = CAMERA_MSG_SHUTTER;
3506     cbArg.ext1 = 0;
3507
3508     if(!m_bShutterSoundPlayed){
3509         cbArg.ext2 = true;
3510         m_cbNotifier.notifyCallback(cbArg);
3511     }
3512     cbArg.ext2 = false;
3513     m_cbNotifier.notifyCallback(cbArg);
3514     m_bShutterSoundPlayed = false;
3515}
3516
3517/*===========================================================================
3518 * FUNCTION   : getChannelByHandle
3519 *
3520 * DESCRIPTION: return a channel by its handle
3521 *
3522 * PARAMETERS :
3523 *   @channelHandle : channel handle
3524 *
3525 * RETURN     : a channel obj if found, NULL if not found
3526 *==========================================================================*/
3527QCameraChannel *QCamera2HardwareInterface::getChannelByHandle(uint32_t channelHandle)
3528{
3529    for(int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
3530        if (m_channels[i] != NULL &&
3531            m_channels[i]->getMyHandle() == channelHandle) {
3532            return m_channels[i];
3533        }
3534    }
3535
3536    return NULL;
3537}
3538
3539/*===========================================================================
3540 * FUNCTION   : processFaceDetectionReuslt
3541 *
3542 * DESCRIPTION: process face detection reuslt
3543 *
3544 * PARAMETERS :
3545 *   @fd_data : ptr to face detection result struct
3546 *
3547 * RETURN     : int32_t type of status
3548 *              NO_ERROR  -- success
3549 *              none-zero failure code
3550 *==========================================================================*/
3551int32_t QCamera2HardwareInterface::processFaceDetectionResult(cam_face_detection_data_t *fd_data)
3552{
3553    if (!mParameters.isFaceDetectionEnabled()) {
3554        ALOGD("%s: FaceDetection not enabled, no ops here", __func__);
3555        return NO_ERROR;
3556    }
3557
3558    if ((NULL == mDataCb) || (msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_METADATA) == 0)) {
3559        ALOGD("%s: prevew metadata msgtype not enabled, no ops here", __func__);
3560        return NO_ERROR;
3561    }
3562
3563    cam_dimension_t display_dim;
3564    mParameters.getStreamDimension(CAM_STREAM_TYPE_PREVIEW, display_dim);
3565    if (display_dim.width <= 0 || display_dim.height <= 0) {
3566        ALOGE("%s: Invalid preview width or height (%d x %d)",
3567              __func__, display_dim.width, display_dim.height);
3568        return UNKNOWN_ERROR;
3569    }
3570
3571    // process face detection result
3572    size_t faceResultSize = sizeof(camera_frame_metadata_t);
3573    faceResultSize += sizeof(camera_face_t) * MAX_ROI;
3574    camera_memory_t *faceResultBuffer = mGetMemory(-1,
3575                                                   faceResultSize,
3576                                                   1,
3577                                                   mCallbackCookie);
3578    if ( NULL == faceResultBuffer ) {
3579        ALOGE("%s: Not enough memory for face result data",
3580              __func__);
3581        return NO_MEMORY;
3582    }
3583
3584    unsigned char *faceData = ( unsigned char * ) faceResultBuffer->data;
3585    memset(faceData, 0, faceResultSize);
3586    camera_frame_metadata_t *roiData = (camera_frame_metadata_t * ) faceData;
3587    camera_face_t *faces = (camera_face_t *) ( faceData + sizeof(camera_frame_metadata_t) );
3588
3589    roiData->number_of_faces = fd_data->num_faces_detected;
3590    roiData->faces = faces;
3591    if (roiData->number_of_faces > 0) {
3592        for (int i = 0; i < roiData->number_of_faces; i++) {
3593            faces[i].id = fd_data->faces[i].face_id;
3594            faces[i].score = fd_data->faces[i].score;
3595
3596            // left
3597            faces[i].rect[0] =
3598                MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].face_boundary.left, display_dim.width, 2000, -1000);
3599
3600            // top
3601            faces[i].rect[1] =
3602                MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].face_boundary.top, display_dim.height, 2000, -1000);
3603
3604            // right
3605            faces[i].rect[2] = faces[i].rect[0] +
3606                MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].face_boundary.width, display_dim.width, 2000, 0);
3607
3608             // bottom
3609            faces[i].rect[3] = faces[i].rect[1] +
3610                MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].face_boundary.height, display_dim.height, 2000, 0);
3611
3612            // Center of left eye
3613            faces[i].left_eye[0] =
3614                MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].left_eye_center.x, display_dim.width, 2000, -1000);
3615
3616            faces[i].left_eye[1] =
3617                MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].left_eye_center.y, display_dim.height, 2000, -1000);
3618
3619            // Center of right eye
3620            faces[i].right_eye[0] =
3621                MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].right_eye_center.x, display_dim.width, 2000, -1000);
3622
3623            faces[i].right_eye[1] =
3624                MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].right_eye_center.y, display_dim.height, 2000, -1000);
3625
3626            // Center of mouth
3627            faces[i].mouth[0] =
3628                MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].mouth_center.x, display_dim.width, 2000, -1000);
3629
3630            faces[i].mouth[1] =
3631                MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].mouth_center.y, display_dim.height, 2000, -1000);
3632
3633#if 0
3634            faces[i].smile_degree = fd_data->faces[i].smile_degree;
3635            faces[i].smile_score = fd_data->faces[i].smile_confidence;
3636            faces[i].blink_detected = fd_data->faces[i].blink_detected;
3637            faces[i].face_recognised = fd_data->faces[i].face_recognised;
3638            faces[i].gaze_angle = fd_data->faces[i].gaze_angle;
3639
3640            // upscale by 2 to recover from demaen downscaling
3641            faces[i].updown_dir = fd_data->faces[i].updown_dir * 2;
3642            faces[i].leftright_dir = fd_data->faces[i].leftright_dir * 2;
3643            faces[i].roll_dir = fd_data->faces[i].roll_dir * 2;
3644
3645            faces[i].leye_blink = fd_data->faces[i].left_blink;
3646            faces[i].reye_blink = fd_data->faces[i].right_blink;
3647            faces[i].left_right_gaze = fd_data->faces[i].left_right_gaze;
3648            faces[i].top_bottom_gaze = fd_data->faces[i].top_bottom_gaze;
3649#endif
3650
3651        }
3652    }
3653
3654    qcamera_callback_argm_t cbArg;
3655    memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
3656    cbArg.cb_type = QCAMERA_DATA_CALLBACK;
3657    cbArg.msg_type = CAMERA_MSG_PREVIEW_METADATA;
3658    cbArg.data = faceResultBuffer;
3659    cbArg.metadata = roiData;
3660    cbArg.user_data = faceResultBuffer;
3661    cbArg.cookie = this;
3662    cbArg.release_cb = releaseCameraMemory;
3663    m_cbNotifier.notifyCallback(cbArg);
3664
3665    return NO_ERROR;
3666}
3667
3668/*===========================================================================
3669 * FUNCTION   : releaseCameraMemory
3670 *
3671 * DESCRIPTION: releases camera memory objects
3672 *
3673 * PARAMETERS :
3674 *   @data    : buffer to be released
3675 *   @cookie  : context data
3676 *
3677 * RETURN     : None
3678 *==========================================================================*/
3679void QCamera2HardwareInterface::releaseCameraMemory(void *data, void */*cookie*/)
3680{
3681    camera_memory_t *mem = ( camera_memory_t * ) data;
3682    if ( NULL != mem ) {
3683        mem->release(mem);
3684    }
3685}
3686
3687/*===========================================================================
3688 * FUNCTION   : returnStreamBuffer
3689 *
3690 * DESCRIPTION: returns back a stream buffer
3691 *
3692 * PARAMETERS :
3693 *   @data    : buffer to be released
3694 *   @cookie  : context data
3695 *
3696 * RETURN     : None
3697 *==========================================================================*/
3698void QCamera2HardwareInterface::returnStreamBuffer(void *data, void *cookie)
3699{
3700    QCameraStream *stream = ( QCameraStream * ) cookie;
3701    int idx = ( int ) data;
3702    if ( ( NULL != stream )) {
3703        stream->bufDone(idx);
3704    }
3705}
3706
3707/*===========================================================================
3708 * FUNCTION   : processHistogramStats
3709 *
3710 * DESCRIPTION: process histogram stats
3711 *
3712 * PARAMETERS :
3713 *   @hist_data : ptr to histogram stats struct
3714 *
3715 * RETURN     : int32_t type of status
3716 *              NO_ERROR  -- success
3717 *              none-zero failure code
3718 *==========================================================================*/
3719int32_t QCamera2HardwareInterface::processHistogramStats(cam_hist_stats_t &/*stats_data*/)
3720{
3721    if (!mParameters.isHistogramEnabled()) {
3722        ALOGD("%s: Histogram not enabled, no ops here", __func__);
3723        return NO_ERROR;
3724    }
3725
3726    camera_memory_t *histBuffer = mGetMemory(-1,
3727                                             sizeof(cam_histogram_data_t),
3728                                             1,
3729                                             mCallbackCookie);
3730    if ( NULL == histBuffer ) {
3731        ALOGE("%s: Not enough memory for histogram data",
3732              __func__);
3733        return NO_MEMORY;
3734    }
3735
3736    cam_histogram_data_t *pHistData = (cam_histogram_data_t *)histBuffer->data;
3737    if (pHistData == NULL) {
3738        ALOGE("%s: memory data ptr is NULL", __func__);
3739        return UNKNOWN_ERROR;
3740    }
3741
3742
3743    return NO_ERROR;
3744}
3745
3746/*===========================================================================
3747 * FUNCTION   : updateThermalLevel
3748 *
3749 * DESCRIPTION: update thermal level depending on thermal events
3750 *
3751 * PARAMETERS :
3752 *   @level   : thermal level
3753 *
3754 * RETURN     : int32_t type of status
3755 *              NO_ERROR  -- success
3756 *              none-zero failure code
3757 *==========================================================================*/
3758int QCamera2HardwareInterface::updateThermalLevel(
3759            qcamera_thermal_level_enum_t level)
3760{
3761    int ret = NO_ERROR;
3762    cam_fps_range_t adjustedRange;
3763    int minFPS, maxFPS;
3764    qcamera_thermal_mode thermalMode = mParameters.getThermalMode();
3765    enum msm_vfe_frame_skip_pattern skipPattern;
3766
3767    mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
3768
3769    switch(level) {
3770    case QCAMERA_THERMAL_NO_ADJUSTMENT:
3771        {
3772            adjustedRange.min_fps = minFPS / 1000.0f;
3773            adjustedRange.max_fps = maxFPS / 1000.0f;
3774            skipPattern = NO_SKIP;
3775        }
3776        break;
3777    case QCAMERA_THERMAL_SLIGHT_ADJUSTMENT:
3778        {
3779            adjustedRange.min_fps = (minFPS / 2) / 1000.0f;
3780            adjustedRange.max_fps = (maxFPS / 2) / 1000.0f;
3781            if ( adjustedRange.min_fps < 1 ) {
3782                adjustedRange.min_fps = 1;
3783            }
3784            if ( adjustedRange.max_fps < 1 ) {
3785                adjustedRange.max_fps = 1;
3786            }
3787            skipPattern = EVERY_2FRAME;
3788        }
3789        break;
3790    case QCAMERA_THERMAL_BIG_ADJUSTMENT:
3791        {
3792            adjustedRange.min_fps = (minFPS / 4) / 1000.0f;
3793            adjustedRange.max_fps = (maxFPS / 4) / 1000.0f;
3794            if ( adjustedRange.min_fps < 1 ) {
3795                adjustedRange.min_fps = 1;
3796            }
3797            if ( adjustedRange.max_fps < 1 ) {
3798                adjustedRange.max_fps = 1;
3799            }
3800            skipPattern = EVERY_4FRAME;
3801        }
3802        break;
3803    case QCAMERA_THERMAL_SHUTDOWN:
3804        {
3805            // Stop Preview?
3806            // Set lowest min FPS for now
3807            adjustedRange.min_fps = minFPS/1000.0f;
3808            adjustedRange.max_fps = minFPS/1000.0f;
3809            for ( int i = 0 ; i < gCamCapability[mCameraId]->fps_ranges_tbl_cnt ; i++ ) {
3810                if ( gCamCapability[mCameraId]->fps_ranges_tbl[i].min_fps < adjustedRange.min_fps ) {
3811                    adjustedRange.min_fps = gCamCapability[mCameraId]->fps_ranges_tbl[i].min_fps;
3812                    adjustedRange.max_fps = adjustedRange.min_fps;
3813                }
3814            }
3815            skipPattern = MAX_SKIP;
3816        }
3817        break;
3818    default:
3819        {
3820            ALOGE("%s: Invalid thermal level %d", __func__, level);
3821            return BAD_VALUE;
3822        }
3823        break;
3824    }
3825
3826    ALOGI("%s: Thermal level %d, FPS range [%3.2f,%3.2f], frameskip %d",
3827          __func__,
3828          level,
3829          adjustedRange.min_fps,
3830          adjustedRange.max_fps,
3831          skipPattern);
3832
3833    if (thermalMode == QCAMERA_THERMAL_ADJUST_FPS)
3834        ret = mParameters.adjustPreviewFpsRange(&adjustedRange);
3835    else if (thermalMode == QCAMERA_THERMAL_ADJUST_FRAMESKIP)
3836        ret = mParameters.setFrameSkip(skipPattern);
3837    else
3838        ALOGE("%s: Incorrect thermal mode %d", __func__, thermalMode);
3839
3840    return ret;
3841
3842}
3843
3844/*===========================================================================
3845 * FUNCTION   : updateParameters
3846 *
3847 * DESCRIPTION: update parameters
3848 *
3849 * PARAMETERS :
3850 *   @parms       : input parameters string
3851 *   @needRestart : output, flag to indicate if preview restart is needed
3852 *
3853 * RETURN     : int32_t type of status
3854 *              NO_ERROR  -- success
3855 *              none-zero failure code
3856 *==========================================================================*/
3857int QCamera2HardwareInterface::updateParameters(const char *parms, bool &needRestart)
3858{
3859    String8 str = String8(parms);
3860    QCameraParameters param(str);
3861    return mParameters.updateParameters(param, needRestart);
3862}
3863
3864/*===========================================================================
3865 * FUNCTION   : commitParameterChanges
3866 *
3867 * DESCRIPTION: commit parameter changes to the backend to take effect
3868 *
3869 * PARAMETERS : none
3870 *
3871 * RETURN     : int32_t type of status
3872 *              NO_ERROR  -- success
3873 *              none-zero failure code
3874 * NOTE       : This function must be called after updateParameters.
3875 *              Otherwise, no change will be passed to backend to take effect.
3876 *==========================================================================*/
3877int QCamera2HardwareInterface::commitParameterChanges()
3878{
3879    int rc = mParameters.commitParameters();
3880    if (rc == NO_ERROR) {
3881        // update number of snapshot based on committed parameters setting
3882        rc = mParameters.setNumOfSnapshot();
3883    }
3884    return rc;
3885}
3886
3887/*===========================================================================
3888 * FUNCTION   : needDebugFps
3889 *
3890 * DESCRIPTION: if fps log info need to be printed out
3891 *
3892 * PARAMETERS : none
3893 *
3894 * RETURN     : true: need print out fps log
3895 *              false: no need to print out fps log
3896 *==========================================================================*/
3897bool QCamera2HardwareInterface::needDebugFps()
3898{
3899    return mParameters.isFpsDebugEnabled();
3900}
3901
3902/*===========================================================================
3903 * FUNCTION   : isCACEnabled
3904 *
3905 * DESCRIPTION: if CAC is enabled
3906 *
3907 * PARAMETERS : none
3908 *
3909 * RETURN     : true: needed
3910 *              false: no need
3911 *==========================================================================*/
3912bool QCamera2HardwareInterface::isCACEnabled()
3913{
3914    char prop[PROPERTY_VALUE_MAX];
3915    memset(prop, 0, sizeof(prop));
3916    property_get("persist.camera.feature.cac", prop, "0");
3917    int enableCAC = atoi(prop);
3918    return enableCAC == 1;
3919}
3920
3921/*===========================================================================
3922 * FUNCTION   : needReprocess
3923 *
3924 * DESCRIPTION: if reprocess is needed
3925 *
3926 * PARAMETERS : none
3927 *
3928 * RETURN     : true: needed
3929 *              false: no need
3930 *==========================================================================*/
3931bool QCamera2HardwareInterface::needReprocess()
3932{
3933    if (!mParameters.isJpegPictureFormat()) {
3934        // RAW image, no need to reprocess
3935        return false;
3936    }
3937
3938    if (((gCamCapability[mCameraId]->min_required_pp_mask > 0) ||
3939         mParameters.isWNREnabled() || isCACEnabled())) {
3940        // TODO: add for ZSL HDR later
3941        ALOGD("%s: need do reprocess for ZSL WNR or min PP reprocess", __func__);
3942        return true;
3943    }
3944
3945    return needRotationReprocess();
3946}
3947
3948/*===========================================================================
3949 * FUNCTION   : needRotationReprocess
3950 *
3951 * DESCRIPTION: if rotation needs to be done by reprocess in pp
3952 *
3953 * PARAMETERS : none
3954 *
3955 * RETURN     : true: needed
3956 *              false: no need
3957 *==========================================================================*/
3958bool QCamera2HardwareInterface::needRotationReprocess()
3959{
3960    if (!mParameters.isJpegPictureFormat()) {
3961        // RAW image, no need to reprocess
3962        return false;
3963    }
3964
3965    if ((gCamCapability[mCameraId]->qcom_supported_feature_mask & CAM_QCOM_FEATURE_ROTATION) > 0 &&
3966        mParameters.getJpegRotation() > 0) {
3967        // current rotation is not zero, and pp has the capability to process rotation
3968        ALOGD("%s: need do reprocess for rotation", __func__);
3969        return true;
3970    }
3971
3972    return false;
3973}
3974
3975/*===========================================================================
3976 * FUNCTION   : getThumbnailSize
3977 *
3978 * DESCRIPTION: get user set thumbnail size
3979 *
3980 * PARAMETERS :
3981 *   @dim     : output of thumbnail dimension
3982 *
3983 * RETURN     : none
3984 *==========================================================================*/
3985void QCamera2HardwareInterface::getThumbnailSize(cam_dimension_t &dim)
3986{
3987    mParameters.getThumbnailSize(&dim.width, &dim.height);
3988}
3989
3990/*===========================================================================
3991 * FUNCTION   : getJpegQuality
3992 *
3993 * DESCRIPTION: get user set jpeg quality
3994 *
3995 * PARAMETERS : none
3996 *
3997 * RETURN     : jpeg quality setting
3998 *==========================================================================*/
3999int QCamera2HardwareInterface::getJpegQuality()
4000{
4001    return mParameters.getJpegQuality();
4002}
4003
4004/*===========================================================================
4005 * FUNCTION   : getJpegRotation
4006 *
4007 * DESCRIPTION: get rotation information to be passed into jpeg encoding
4008 *
4009 * PARAMETERS : none
4010 *
4011 * RETURN     : rotation information
4012 *==========================================================================*/
4013int QCamera2HardwareInterface::getJpegRotation() {
4014    return mParameters.getJpegRotation();
4015}
4016
4017/*===========================================================================
4018 * FUNCTION   : getExifData
4019 *
4020 * DESCRIPTION: get exif data to be passed into jpeg encoding
4021 *
4022 * PARAMETERS : none
4023 *
4024 * RETURN     : exif data from user setting and GPS
4025 *==========================================================================*/
4026QCameraExif *QCamera2HardwareInterface::getExifData()
4027{
4028    QCameraExif *exif = new QCameraExif();
4029    if (exif == NULL) {
4030        ALOGE("%s: No memory for QCameraExif", __func__);
4031        return NULL;
4032    }
4033
4034    int32_t rc = NO_ERROR;
4035    uint32_t count = 0;
4036
4037    // add exif entries
4038    char dateTime[20];
4039    memset(dateTime, 0, sizeof(dateTime));
4040    count = 20;
4041    rc = mParameters.getExifDateTime(dateTime, count);
4042    if(rc == NO_ERROR) {
4043        exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL,
4044                       EXIF_ASCII,
4045                       count,
4046                       (void *)dateTime);
4047    } else {
4048        ALOGE("%s: getExifDateTime failed", __func__);
4049    }
4050
4051    rat_t focalLength;
4052    rc = mParameters.getExifFocalLength(&focalLength);
4053    if (rc == NO_ERROR) {
4054        exif->addEntry(EXIFTAGID_FOCAL_LENGTH,
4055                       EXIF_RATIONAL,
4056                       1,
4057                       (void *)&(focalLength));
4058    } else {
4059        ALOGE("%s: getExifFocalLength failed", __func__);
4060    }
4061
4062    uint16_t isoSpeed = mParameters.getExifIsoSpeed();
4063    exif->addEntry(EXIFTAGID_ISO_SPEED_RATING,
4064                   EXIF_SHORT,
4065                   1,
4066                   (void *)&(isoSpeed));
4067
4068    char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE];
4069    count = 0;
4070    rc = mParameters.getExifGpsProcessingMethod(gpsProcessingMethod, count);
4071    if(rc == NO_ERROR) {
4072        exif->addEntry(EXIFTAGID_GPS_PROCESSINGMETHOD,
4073                       EXIF_ASCII,
4074                       count,
4075                       (void *)gpsProcessingMethod);
4076    } else {
4077        ALOGE("%s: getExifGpsProcessingMethod failed", __func__);
4078    }
4079
4080    rat_t latitude[3];
4081    char latRef[2];
4082    rc = mParameters.getExifLatitude(latitude, latRef);
4083    if(rc == NO_ERROR) {
4084        exif->addEntry(EXIFTAGID_GPS_LATITUDE,
4085                       EXIF_RATIONAL,
4086                       3,
4087                       (void *)latitude);
4088        exif->addEntry(EXIFTAGID_GPS_LATITUDE_REF,
4089                       EXIF_ASCII,
4090                       2,
4091                       (void *)latRef);
4092    } else {
4093        ALOGE("%s: getExifLatitude failed", __func__);
4094    }
4095
4096    rat_t longitude[3];
4097    char lonRef[2];
4098    rc = mParameters.getExifLongitude(longitude, lonRef);
4099    if(rc == NO_ERROR) {
4100        exif->addEntry(EXIFTAGID_GPS_LONGITUDE,
4101                       EXIF_RATIONAL,
4102                       3,
4103                       (void *)longitude);
4104
4105        exif->addEntry(EXIFTAGID_GPS_LONGITUDE_REF,
4106                       EXIF_ASCII,
4107                       2,
4108                       (void *)lonRef);
4109    } else {
4110        ALOGE("%s: getExifLongitude failed", __func__);
4111    }
4112
4113    rat_t altitude;
4114    char altRef;
4115    rc = mParameters.getExifAltitude(&altitude, &altRef);
4116    if(rc == NO_ERROR) {
4117        exif->addEntry(EXIFTAGID_GPS_ALTITUDE,
4118                       EXIF_RATIONAL,
4119                       1,
4120                       (void *)&(altitude));
4121
4122        exif->addEntry(EXIFTAGID_GPS_ALTITUDE_REF,
4123                       EXIF_BYTE,
4124                       1,
4125                       (void *)&altRef);
4126    } else {
4127        ALOGE("%s: getExifAltitude failed", __func__);
4128    }
4129
4130    char gpsDateStamp[20];
4131    rat_t gpsTimeStamp[3];
4132    rc = mParameters.getExifGpsDateTimeStamp(gpsDateStamp, 20, gpsTimeStamp);
4133    if(rc == NO_ERROR) {
4134        exif->addEntry(EXIFTAGID_GPS_DATESTAMP,
4135                       EXIF_ASCII,
4136                       strlen(gpsDateStamp) + 1,
4137                       (void *)gpsDateStamp);
4138
4139        exif->addEntry(EXIFTAGID_GPS_TIMESTAMP,
4140                       EXIF_RATIONAL,
4141                       3,
4142                       (void *)gpsTimeStamp);
4143    } else {
4144        ALOGE("%s: getExifGpsDataTimeStamp failed", __func__);
4145    }
4146
4147    return exif;
4148}
4149
4150/*===========================================================================
4151 * FUNCTION   : setHistogram
4152 *
4153 * DESCRIPTION: set if histogram should be enabled
4154 *
4155 * PARAMETERS :
4156 *   @histogram_en : bool flag if histogram should be enabled
4157 *
4158 * RETURN     : int32_t type of status
4159 *              NO_ERROR  -- success
4160 *              none-zero failure code
4161 *==========================================================================*/
4162int32_t QCamera2HardwareInterface::setHistogram(bool histogram_en)
4163{
4164    return mParameters.setHistogram(histogram_en);
4165}
4166
4167/*===========================================================================
4168 * FUNCTION   : setFaceDetection
4169 *
4170 * DESCRIPTION: set if face detection should be enabled
4171 *
4172 * PARAMETERS :
4173 *   @enabled : bool flag if face detection should be enabled
4174 *
4175 * RETURN     : int32_t type of status
4176 *              NO_ERROR  -- success
4177 *              none-zero failure code
4178 *==========================================================================*/
4179int32_t QCamera2HardwareInterface::setFaceDetection(bool enabled)
4180{
4181    return mParameters.setFaceDetection(enabled);
4182}
4183
4184/*===========================================================================
4185 * FUNCTION   : prepareHardwareForSnapshot
4186 *
4187 * DESCRIPTION: prepare hardware for snapshot, such as LED
4188 *
4189 * PARAMETERS :
4190 *   @afNeeded: flag indicating if Auto Focus needs to be done during preparation
4191 *
4192 * RETURN     : int32_t type of status
4193 *              NO_ERROR  -- success
4194 *              none-zero failure code
4195 *==========================================================================*/
4196int32_t QCamera2HardwareInterface::prepareHardwareForSnapshot(int32_t afNeeded)
4197{
4198    ALOGD("[KPI Perf] %s: Prepare hardware such as LED",__func__);
4199    return mCameraHandle->ops->prepare_snapshot(mCameraHandle->camera_handle,
4200                                                afNeeded);
4201}
4202
4203}; // namespace qcamera
4204