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