QCamera2HWI.cpp revision fde009c21f68cbf3562e68b88603730f9d416f3c
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            rc = addCaptureChannel();
1927            if (rc == NO_ERROR) {
1928                // start postprocessor
1929                m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_CAPTURE]);
1930
1931                // start catpure channel
1932                rc = startChannel(QCAMERA_CH_TYPE_CAPTURE);
1933                if (rc != NO_ERROR) {
1934                    ALOGE("%s: cannot start capture channel", __func__);
1935                    m_postprocessor.stop();
1936                    delChannel(QCAMERA_CH_TYPE_CAPTURE);
1937                    return rc;
1938                }
1939            } else {
1940                ALOGE("%s: cannot add capture channel", __func__);
1941                return rc;
1942            }
1943        } else {
1944            rc = addRawChannel();
1945            if (rc == NO_ERROR) {
1946                // start postprocessor
1947                m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]);
1948                rc = startChannel(QCAMERA_CH_TYPE_RAW);
1949                if (rc != NO_ERROR) {
1950                    ALOGE("%s: cannot start raw channel", __func__);
1951                    m_postprocessor.stop();
1952                    delChannel(QCAMERA_CH_TYPE_RAW);
1953                    return rc;
1954                }
1955            } else {
1956                ALOGE("%s: cannot add raw channel", __func__);
1957                return rc;
1958            }
1959        }
1960    }
1961    ALOGD("%s: X", __func__);
1962    return rc;
1963}
1964
1965/*===========================================================================
1966 * FUNCTION   : cancelPicture
1967 *
1968 * DESCRIPTION: cancel picture impl
1969 *
1970 * PARAMETERS : none
1971 *
1972 * RETURN     : int32_t type of status
1973 *              NO_ERROR  -- success
1974 *              none-zero failure code
1975 *==========================================================================*/
1976int QCamera2HardwareInterface::cancelPicture()
1977{
1978    //stop post processor
1979    m_postprocessor.stop();
1980
1981    if (mParameters.isZSLMode()) {
1982        QCameraPicChannel *pZSLChannel =
1983            (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
1984        if (NULL != pZSLChannel) {
1985            if (m_bStartZSLSnapshotCalled) {
1986                mCameraHandle->ops->stop_zsl_snapshot(
1987                        mCameraHandle->camera_handle);
1988                m_bStartZSLSnapshotCalled = false;
1989            }
1990            pZSLChannel->cancelPicture();
1991        }
1992    } else {
1993        // normal capture case
1994        if (mParameters.isJpegPictureFormat()) {
1995            stopChannel(QCAMERA_CH_TYPE_CAPTURE);
1996            delChannel(QCAMERA_CH_TYPE_CAPTURE);
1997        } else {
1998            stopChannel(QCAMERA_CH_TYPE_RAW);
1999            delChannel(QCAMERA_CH_TYPE_RAW);
2000        }
2001    }
2002    return NO_ERROR;
2003}
2004
2005/*===========================================================================
2006 * FUNCTION   : takeLiveSnapshot
2007 *
2008 * DESCRIPTION: take live snapshot during recording
2009 *
2010 * PARAMETERS : none
2011 *
2012 * RETURN     : int32_t type of status
2013 *              NO_ERROR  -- success
2014 *              none-zero failure code
2015 *==========================================================================*/
2016int QCamera2HardwareInterface::takeLiveSnapshot()
2017{
2018    int rc = NO_ERROR;
2019
2020    // start post processor
2021    rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_SNAPSHOT]);
2022
2023    // start snapshot channel
2024    if (rc == NO_ERROR) {
2025        rc = startChannel(QCAMERA_CH_TYPE_SNAPSHOT);
2026    }
2027    return rc;
2028}
2029
2030/*===========================================================================
2031 * FUNCTION   : cancelLiveSnapshot
2032 *
2033 * DESCRIPTION: cancel current live snapshot request
2034 *
2035 * PARAMETERS : none
2036 *
2037 * RETURN     : int32_t type of status
2038 *              NO_ERROR  -- success
2039 *              none-zero failure code
2040 *==========================================================================*/
2041int QCamera2HardwareInterface::cancelLiveSnapshot()
2042{
2043    int rc = NO_ERROR;
2044
2045    //stop post processor
2046    m_postprocessor.stop();
2047
2048    // stop snapshot channel
2049    rc = stopChannel(QCAMERA_CH_TYPE_SNAPSHOT);
2050
2051    return rc;
2052}
2053
2054/*===========================================================================
2055 * FUNCTION   : getParameters
2056 *
2057 * DESCRIPTION: get parameters impl
2058 *
2059 * PARAMETERS : none
2060 *
2061 * RETURN     : a string containing parameter pairs
2062 *==========================================================================*/
2063char* QCamera2HardwareInterface::getParameters()
2064{
2065    char* strParams = NULL;
2066    String8 str;
2067    str = mParameters.flatten( );
2068    strParams = (char *)malloc(sizeof(char)*(str.length()+1));
2069    if(strParams != NULL){
2070        memset(strParams, 0, sizeof(char)*(str.length()+1));
2071        strncpy(strParams, str.string(), str.length());
2072        strParams[str.length()] = 0;
2073    }
2074    return strParams;
2075}
2076
2077/*===========================================================================
2078 * FUNCTION   : putParameters
2079 *
2080 * DESCRIPTION: put parameters string impl
2081 *
2082 * PARAMETERS :
2083 *   @parms   : parameters string to be released
2084 *
2085 * RETURN     : int32_t type of status
2086 *              NO_ERROR  -- success
2087 *              none-zero failure code
2088 *==========================================================================*/
2089int QCamera2HardwareInterface::putParameters(char *parms)
2090{
2091    free(parms);
2092    return NO_ERROR;
2093}
2094
2095/*===========================================================================
2096 * FUNCTION   : sendCommand
2097 *
2098 * DESCRIPTION: send command impl
2099 *
2100 * PARAMETERS :
2101 *   @command : command to be executed
2102 *   @arg1    : optional argument 1
2103 *   @arg2    : optional argument 2
2104 *
2105 * RETURN     : int32_t type of status
2106 *              NO_ERROR  -- success
2107 *              none-zero failure code
2108 *==========================================================================*/
2109int QCamera2HardwareInterface::sendCommand(int32_t command, int32_t /*arg1*/, int32_t /*arg2*/)
2110{
2111    int rc = NO_ERROR;
2112
2113    switch (command) {
2114    case CAMERA_CMD_START_FACE_DETECTION:
2115    case CAMERA_CMD_STOP_FACE_DETECTION:
2116        rc = setFaceDetection(command == CAMERA_CMD_START_FACE_DETECTION? true : false);
2117        break;
2118    default:
2119        rc = NO_ERROR;
2120        break;
2121    }
2122    return rc;
2123}
2124
2125/*===========================================================================
2126 * FUNCTION   : registerFaceImage
2127 *
2128 * DESCRIPTION: register face image impl
2129 *
2130 * PARAMETERS :
2131 *   @img_ptr : ptr to image buffer
2132 *   @config  : ptr to config struct about input image info
2133 *   @faceID  : [OUT] face ID to uniquely identifiy the registered face image
2134 *
2135 * RETURN     : int32_t type of status
2136 *              NO_ERROR  -- success
2137 *              none-zero failure code
2138 *==========================================================================*/
2139int QCamera2HardwareInterface::registerFaceImage(void *img_ptr,
2140                                                 cam_pp_offline_src_config_t *config,
2141                                                 int32_t &faceID)
2142{
2143    int rc = NO_ERROR;
2144    faceID = -1;
2145
2146    if (img_ptr == NULL || config == NULL) {
2147        ALOGE("%s: img_ptr or config is NULL", __func__);
2148        return BAD_VALUE;
2149    }
2150
2151    // allocate ion memory for source image
2152    QCameraHeapMemory *imgBuf = new QCameraHeapMemory();
2153    if (imgBuf == NULL) {
2154        ALOGE("%s: Unable to new heap memory obj for image buf", __func__);
2155        return NO_MEMORY;
2156    }
2157
2158    rc = imgBuf->allocate(1, config->input_buf_planes.plane_info.frame_len);
2159    if (rc < 0) {
2160        ALOGE("%s: Unable to allocate heap memory for image buf", __func__);
2161        delete imgBuf;
2162        return NO_MEMORY;
2163    }
2164
2165    void *pBufPtr = imgBuf->getPtr(0);
2166    if (pBufPtr == NULL) {
2167        ALOGE("%s: image buf is NULL", __func__);
2168        imgBuf->deallocate();
2169        delete imgBuf;
2170        return NO_MEMORY;
2171    }
2172    memcpy(pBufPtr, img_ptr, config->input_buf_planes.plane_info.frame_len);
2173
2174    cam_pp_feature_config_t pp_feature;
2175    memset(&pp_feature, 0, sizeof(cam_pp_feature_config_t));
2176    pp_feature.feature_mask = CAM_QCOM_FEATURE_REGISTER_FACE;
2177    QCameraReprocessChannel *pChannel =
2178        addOfflineReprocChannel(*config, pp_feature, NULL, NULL);
2179
2180    if (pChannel == NULL) {
2181        ALOGE("%s: fail to add offline reprocess channel", __func__);
2182        imgBuf->deallocate();
2183        delete imgBuf;
2184        return UNKNOWN_ERROR;
2185    }
2186
2187    rc = pChannel->start(mParameters);
2188    if (rc != NO_ERROR) {
2189        ALOGE("%s: Cannot start reprocess channel", __func__);
2190        imgBuf->deallocate();
2191        delete imgBuf;
2192        delete pChannel;
2193        return rc;
2194    }
2195
2196    rc = pChannel->doReprocess(imgBuf->getFd(0), imgBuf->getSize(0), faceID);
2197
2198    // done with register face image, free imgbuf and delete reprocess channel
2199    imgBuf->deallocate();
2200    delete imgBuf;
2201    imgBuf = NULL;
2202    pChannel->stop();
2203    delete pChannel;
2204    pChannel = NULL;
2205
2206    return rc;
2207}
2208
2209/*===========================================================================
2210 * FUNCTION   : release
2211 *
2212 * DESCRIPTION: release camera resource impl
2213 *
2214 * PARAMETERS : none
2215 *
2216 * RETURN     : int32_t type of status
2217 *              NO_ERROR  -- success
2218 *              none-zero failure code
2219 *==========================================================================*/
2220int QCamera2HardwareInterface::release()
2221{
2222    // stop and delete all channels
2223    for (int i = 0; i <QCAMERA_CH_TYPE_MAX ; i++) {
2224        if (m_channels[i] != NULL) {
2225            stopChannel((qcamera_ch_type_enum_t)i);
2226            delChannel((qcamera_ch_type_enum_t)i);
2227        }
2228    }
2229
2230    return NO_ERROR;
2231}
2232
2233/*===========================================================================
2234 * FUNCTION   : dump
2235 *
2236 * DESCRIPTION: camera status dump impl
2237 *
2238 * PARAMETERS :
2239 *   @fd      : fd for the buffer to be dumped with camera status
2240 *
2241 * RETURN     : int32_t type of status
2242 *              NO_ERROR  -- success
2243 *              none-zero failure code
2244 *==========================================================================*/
2245int QCamera2HardwareInterface::dump(int /*fd*/)
2246{
2247    ALOGE("%s: not supported yet", __func__);
2248    return INVALID_OPERATION;
2249}
2250
2251/*===========================================================================
2252 * FUNCTION   : processAPI
2253 *
2254 * DESCRIPTION: process API calls from upper layer
2255 *
2256 * PARAMETERS :
2257 *   @api         : API to be processed
2258 *   @api_payload : ptr to API payload if any
2259 *
2260 * RETURN     : int32_t type of status
2261 *              NO_ERROR  -- success
2262 *              none-zero failure code
2263 *==========================================================================*/
2264int QCamera2HardwareInterface::processAPI(qcamera_sm_evt_enum_t api, void *api_payload)
2265{
2266    return m_stateMachine.procAPI(api, api_payload);
2267}
2268
2269/*===========================================================================
2270 * FUNCTION   : processEvt
2271 *
2272 * DESCRIPTION: process Evt from backend via mm-camera-interface
2273 *
2274 * PARAMETERS :
2275 *   @evt         : event type to be processed
2276 *   @evt_payload : ptr to event payload if any
2277 *
2278 * RETURN     : int32_t type of status
2279 *              NO_ERROR  -- success
2280 *              none-zero failure code
2281 *==========================================================================*/
2282int QCamera2HardwareInterface::processEvt(qcamera_sm_evt_enum_t evt, void *evt_payload)
2283{
2284    return m_stateMachine.procEvt(evt, evt_payload);
2285}
2286
2287/*===========================================================================
2288 * FUNCTION   : evtHandle
2289 *
2290 * DESCRIPTION: Function registerd to mm-camera-interface to handle backend events
2291 *
2292 * PARAMETERS :
2293 *   @camera_handle : event type to be processed
2294 *   @evt           : ptr to event
2295 *   @user_data     : user data ptr
2296 *
2297 * RETURN     : none
2298 *==========================================================================*/
2299void QCamera2HardwareInterface::camEvtHandle(uint32_t /*camera_handle*/,
2300                                          mm_camera_event_t *evt,
2301                                          void *user_data)
2302{
2303    QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)user_data;
2304    if (obj && evt) {
2305        mm_camera_event_t *payload =
2306            (mm_camera_event_t *)malloc(sizeof(mm_camera_event_t));
2307        if (NULL != payload) {
2308            *payload = *evt;
2309            obj->processEvt(QCAMERA_SM_EVT_EVT_NOTIFY, payload);
2310        }
2311    } else {
2312        ALOGE("%s: NULL user_data", __func__);
2313    }
2314}
2315
2316/*===========================================================================
2317 * FUNCTION   : jpegEvtHandle
2318 *
2319 * DESCRIPTION: Function registerd to mm-jpeg-interface to handle jpeg events
2320 *
2321 * PARAMETERS :
2322 *   @status    : status of jpeg job
2323 *   @client_hdl: jpeg client handle
2324 *   @jobId     : jpeg job Id
2325 *   @p_ouput   : ptr to jpeg output result struct
2326 *   @userdata  : user data ptr
2327 *
2328 * RETURN     : none
2329 *==========================================================================*/
2330void QCamera2HardwareInterface::jpegEvtHandle(jpeg_job_status_t status,
2331                                              uint32_t /*client_hdl*/,
2332                                              uint32_t jobId,
2333                                              mm_jpeg_output_t *p_output,
2334                                              void *userdata)
2335{
2336    QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)userdata;
2337    if (obj) {
2338        qcamera_jpeg_evt_payload_t *payload =
2339            (qcamera_jpeg_evt_payload_t *)malloc(sizeof(qcamera_jpeg_evt_payload_t));
2340        if (NULL != payload) {
2341            memset(payload, 0, sizeof(qcamera_jpeg_evt_payload_t));
2342            payload->status = status;
2343            payload->jobId = jobId;
2344            if (p_output != NULL) {
2345                payload->out_data = *p_output;
2346            }
2347            obj->processEvt(QCAMERA_SM_EVT_JPEG_EVT_NOTIFY, payload);
2348        }
2349    } else {
2350        ALOGE("%s: NULL user_data", __func__);
2351    }
2352}
2353
2354/*===========================================================================
2355 * FUNCTION   : thermalEvtHandle
2356 *
2357 * DESCRIPTION: routine to handle thermal event notification
2358 *
2359 * PARAMETERS :
2360 *   @level      : thermal level
2361 *   @userdata   : userdata passed in during registration
2362 *   @data       : opaque data from thermal client
2363 *
2364 * RETURN     : int32_t type of status
2365 *              NO_ERROR  -- success
2366 *              none-zero failure code
2367 *==========================================================================*/
2368int QCamera2HardwareInterface::thermalEvtHandle(
2369        qcamera_thermal_level_enum_t level, void *userdata, void *data)
2370{
2371    // Make sure thermal events are logged
2372    ALOGI("%s: level = %d, userdata = %p, data = %p",
2373        __func__, level, userdata, data);
2374    //We don't need to lockAPI, waitAPI here. QCAMERA_SM_EVT_THERMAL_NOTIFY
2375    // becomes an aync call. This also means we can only pass payload
2376    // by value, not by address.
2377    return processAPI(QCAMERA_SM_EVT_THERMAL_NOTIFY, (void *)level);
2378}
2379
2380/*===========================================================================
2381 * FUNCTION   : sendEvtNotify
2382 *
2383 * DESCRIPTION: send event notify to notify thread
2384 *
2385 * PARAMETERS :
2386 *   @msg_type: msg type to be sent
2387 *   @ext1    : optional extension1
2388 *   @ext2    : optional extension2
2389 *
2390 * RETURN     : int32_t type of status
2391 *              NO_ERROR  -- success
2392 *              none-zero failure code
2393 *==========================================================================*/
2394int32_t QCamera2HardwareInterface::sendEvtNotify(int32_t msg_type,
2395                                                 int32_t ext1,
2396                                                 int32_t ext2)
2397{
2398    qcamera_callback_argm_t cbArg;
2399    memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
2400    cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK;
2401    cbArg.msg_type = msg_type;
2402    cbArg.ext1 = ext1;
2403    cbArg.ext2 = ext2;
2404    return m_cbNotifier.notifyCallback(cbArg);
2405}
2406
2407/*===========================================================================
2408 * FUNCTION   : processAutoFocusEvent
2409 *
2410 * DESCRIPTION: process auto focus event
2411 *
2412 * PARAMETERS :
2413 *   @focus_data: struct containing auto focus result info
2414 *
2415 * RETURN     : int32_t type of status
2416 *              NO_ERROR  -- success
2417 *              none-zero failure code
2418 *==========================================================================*/
2419int32_t QCamera2HardwareInterface::processAutoFocusEvent(cam_auto_focus_data_t &focus_data)
2420{
2421    int32_t ret = NO_ERROR;
2422
2423    m_currentFocusState = focus_data.focus_state;
2424
2425    cam_focus_mode_type focusMode = mParameters.getFocusMode();
2426    switch (focusMode) {
2427    case CAM_FOCUS_MODE_AUTO:
2428    case CAM_FOCUS_MODE_MACRO:
2429        if (mParameters.isAFRunning()) {
2430            if (focus_data.focus_state == CAM_AF_SCANNING) {
2431                // in the middle of focusing, just ignore it
2432                break;
2433            }
2434
2435            // update focus distance
2436            mParameters.updateFocusDistances(&focus_data.focus_dist);
2437            ret = sendEvtNotify(CAMERA_MSG_FOCUS,
2438                                (focus_data.focus_state == CAM_AF_FOCUSED)? true : false,
2439                                0);
2440            mParameters.setAFRunning(false);
2441        } else {
2442            ret = UNKNOWN_ERROR;
2443            ALOGE("%s: autoFocusEvent when no auto_focus running", __func__);
2444        }
2445        break;
2446    case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
2447    case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
2448        if (focus_data.focus_state == CAM_AF_FOCUSED ||
2449            focus_data.focus_state == CAM_AF_NOT_FOCUSED) {
2450            // update focus distance
2451            mParameters.updateFocusDistances(&focus_data.focus_dist);
2452            if (mParameters.isLockCAFNeeded()) {
2453                mParameters.setLockCAFNeeded(false);
2454                ret = mParameters.setLockCAF(true);
2455            }
2456
2457            ret = sendEvtNotify(CAMERA_MSG_FOCUS,
2458                  (focus_data.focus_state == CAM_AF_FOCUSED)? true : false,
2459                  0);
2460        }
2461        ret = sendEvtNotify(CAMERA_MSG_FOCUS_MOVE,
2462                (focus_data.focus_state == CAM_AF_SCANNING)? true : false,
2463                0);
2464        break;
2465    case CAM_FOCUS_MODE_INFINITY:
2466    case CAM_FOCUS_MODE_FIXED:
2467    case CAM_FOCUS_MODE_EDOF:
2468    default:
2469        ALOGD("%s: no ops for autofocus event in focusmode %d", __func__, focusMode);
2470        break;
2471    }
2472
2473    return ret;
2474}
2475
2476/*===========================================================================
2477 * FUNCTION   : processZoomEvent
2478 *
2479 * DESCRIPTION: process zoom event
2480 *
2481 * PARAMETERS :
2482 *   @crop_info : crop info as a result of zoom operation
2483 *
2484 * RETURN     : int32_t type of status
2485 *              NO_ERROR  -- success
2486 *              none-zero failure code
2487 *==========================================================================*/
2488int32_t QCamera2HardwareInterface::processZoomEvent(cam_crop_data_t &crop_info)
2489{
2490    int32_t ret = NO_ERROR;
2491
2492    for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
2493        if (m_channels[i] != NULL) {
2494            ret = m_channels[i]->processZoomDone(mPreviewWindow, crop_info);
2495        }
2496    }
2497    return ret;
2498}
2499
2500/*===========================================================================
2501 * FUNCTION   : processPrepSnapshotDone
2502 *
2503 * DESCRIPTION: process prep snapshot done event
2504 *
2505 * PARAMETERS :
2506 *   @prep_snapshot_state  : state of prepare snapshot done. In other words,
2507 *                           i.e. whether need future frames for capture.
2508 *
2509 * RETURN     : int32_t type of status
2510 *              NO_ERROR  -- success
2511 *              none-zero failure code
2512 *==========================================================================*/
2513int32_t QCamera2HardwareInterface::processPrepSnapshotDoneEvent(
2514                        cam_prep_snapshot_state_t prep_snapshot_state)
2515{
2516    int32_t ret = NO_ERROR;
2517
2518    if (m_channels[QCAMERA_CH_TYPE_ZSL] &&
2519        prep_snapshot_state == NEED_FUTURE_FRAME) {
2520
2521        ret = mCameraHandle->ops->start_zsl_snapshot(
2522                            mCameraHandle->camera_handle);
2523        if (ret < 0) {
2524            ALOGE("%s: start_led_zsl_capture failed %d",
2525                            __func__, ret);
2526            return ret;
2527        }
2528        m_bStartZSLSnapshotCalled = true;
2529    }
2530    return ret;
2531}
2532
2533/*===========================================================================
2534 * FUNCTION   : processJpegNotify
2535 *
2536 * DESCRIPTION: process jpeg event
2537 *
2538 * PARAMETERS :
2539 *   @jpeg_evt: ptr to jpeg event payload
2540 *
2541 * RETURN     : int32_t type of status
2542 *              NO_ERROR  -- success
2543 *              none-zero failure code
2544 *==========================================================================*/
2545int32_t QCamera2HardwareInterface::processJpegNotify(qcamera_jpeg_evt_payload_t *jpeg_evt)
2546{
2547    return m_postprocessor.processJpegEvt(jpeg_evt);
2548}
2549
2550/*===========================================================================
2551 * FUNCTION   : lockAPI
2552 *
2553 * DESCRIPTION: lock to process API
2554 *
2555 * PARAMETERS : none
2556 *
2557 * RETURN     : none
2558 *==========================================================================*/
2559void QCamera2HardwareInterface::lockAPI()
2560{
2561    pthread_mutex_lock(&m_lock);
2562}
2563
2564/*===========================================================================
2565 * FUNCTION   : waitAPIResult
2566 *
2567 * DESCRIPTION: wait for API result coming back. This is a blocking call, it will
2568 *              return only cerntain API event type arrives
2569 *
2570 * PARAMETERS :
2571 *   @api_evt : API event type
2572 *
2573 * RETURN     : none
2574 *==========================================================================*/
2575void QCamera2HardwareInterface::waitAPIResult(qcamera_sm_evt_enum_t api_evt)
2576{
2577    ALOGV("%s: wait for API result of evt (%d)", __func__, api_evt);
2578    memset(&m_apiResult, 0, sizeof(qcamera_api_result_t));
2579    while (m_apiResult.request_api != api_evt) {
2580        pthread_cond_wait(&m_cond, &m_lock);
2581    }
2582    ALOGV("%s: return (%d) from API result wait for evt (%d)",
2583          __func__, m_apiResult.status, api_evt);
2584}
2585
2586/*===========================================================================
2587 * FUNCTION   : unlockAPI
2588 *
2589 * DESCRIPTION: API processing is done, unlock
2590 *
2591 * PARAMETERS : none
2592 *
2593 * RETURN     : none
2594 *==========================================================================*/
2595void QCamera2HardwareInterface::unlockAPI()
2596{
2597    pthread_mutex_unlock(&m_lock);
2598}
2599
2600/*===========================================================================
2601 * FUNCTION   : signalAPIResult
2602 *
2603 * DESCRIPTION: signal condition viarable that cerntain API event type arrives
2604 *
2605 * PARAMETERS :
2606 *   @result  : API result
2607 *
2608 * RETURN     : none
2609 *==========================================================================*/
2610void QCamera2HardwareInterface::signalAPIResult(qcamera_api_result_t *result)
2611{
2612    pthread_mutex_lock(&m_lock);
2613    m_apiResult = *result;
2614    pthread_cond_signal(&m_cond);
2615    pthread_mutex_unlock(&m_lock);
2616}
2617
2618/*===========================================================================
2619 * FUNCTION   : addStreamToChannel
2620 *
2621 * DESCRIPTION: add a stream into a channel
2622 *
2623 * PARAMETERS :
2624 *   @pChannel   : ptr to channel obj
2625 *   @streamType : type of stream to be added
2626 *   @streamCB   : callback of stream
2627 *   @userData   : user data ptr to callback
2628 *
2629 * RETURN     : int32_t type of status
2630 *              NO_ERROR  -- success
2631 *              none-zero failure code
2632 *==========================================================================*/
2633int32_t QCamera2HardwareInterface::addStreamToChannel(QCameraChannel *pChannel,
2634                                                      cam_stream_type_t streamType,
2635                                                      stream_cb_routine streamCB,
2636                                                      void *userData)
2637{
2638    int32_t rc = NO_ERROR;
2639    QCameraHeapMemory *pStreamInfo = allocateStreamInfoBuf(streamType);
2640    if (pStreamInfo == NULL) {
2641        ALOGE("%s: no mem for stream info buf", __func__);
2642        return NO_MEMORY;
2643    }
2644    uint8_t minStreamBufNum = getBufNumRequired(streamType);
2645    rc = pChannel->addStream(*this,
2646                             pStreamInfo,
2647                             minStreamBufNum,
2648                             &gCamCapability[mCameraId]->padding_info,
2649                             streamCB, userData);
2650    if (rc != NO_ERROR) {
2651        ALOGE("%s: add stream type (%d) failed, ret = %d",
2652              __func__, streamType, rc);
2653        pStreamInfo->deallocate();
2654        delete pStreamInfo;
2655        return rc;
2656    }
2657
2658    return rc;
2659}
2660
2661/*===========================================================================
2662 * FUNCTION   : addPreviewChannel
2663 *
2664 * DESCRIPTION: add a preview channel that contains a preview stream
2665 *
2666 * PARAMETERS : none
2667 *
2668 * RETURN     : int32_t type of status
2669 *              NO_ERROR  -- success
2670 *              none-zero failure code
2671 *==========================================================================*/
2672int32_t QCamera2HardwareInterface::addPreviewChannel()
2673{
2674    int32_t rc = NO_ERROR;
2675    QCameraChannel *pChannel = NULL;
2676
2677    if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
2678        // if we had preview channel before, delete it first
2679        delete m_channels[QCAMERA_CH_TYPE_PREVIEW];
2680        m_channels[QCAMERA_CH_TYPE_PREVIEW] = NULL;
2681    }
2682
2683    pChannel = new QCameraChannel(mCameraHandle->camera_handle,
2684                                  mCameraHandle->ops);
2685    if (NULL == pChannel) {
2686        ALOGE("%s: no mem for preview channel", __func__);
2687        return NO_MEMORY;
2688    }
2689
2690    // preview only channel, don't need bundle attr and cb
2691    rc = pChannel->init(NULL, NULL, NULL);
2692    if (rc != NO_ERROR) {
2693        ALOGE("%s: init preview channel failed, ret = %d", __func__, rc);
2694        delete pChannel;
2695        return rc;
2696    }
2697
2698    // meta data stream always coexists with preview if applicable
2699    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
2700                            metadata_stream_cb_routine, this);
2701    if (rc != NO_ERROR) {
2702        ALOGE("%s: add metadata stream failed, ret = %d", __func__, rc);
2703        delete pChannel;
2704        return rc;
2705    }
2706
2707    if (isNoDisplayMode()) {
2708        rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
2709                                nodisplay_preview_stream_cb_routine, this);
2710    } else {
2711        rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
2712                                preview_stream_cb_routine, this);
2713    }
2714    if (rc != NO_ERROR) {
2715        ALOGE("%s: add preview stream failed, ret = %d", __func__, rc);
2716        delete pChannel;
2717        return rc;
2718    }
2719
2720    m_channels[QCAMERA_CH_TYPE_PREVIEW] = pChannel;
2721    return rc;
2722}
2723
2724/*===========================================================================
2725 * FUNCTION   : addVideoChannel
2726 *
2727 * DESCRIPTION: add a video channel that contains a video stream
2728 *
2729 * PARAMETERS : none
2730 *
2731 * RETURN     : int32_t type of status
2732 *              NO_ERROR  -- success
2733 *              none-zero failure code
2734 *==========================================================================*/
2735int32_t QCamera2HardwareInterface::addVideoChannel()
2736{
2737    int32_t rc = NO_ERROR;
2738    QCameraVideoChannel *pChannel = NULL;
2739
2740    if (m_channels[QCAMERA_CH_TYPE_VIDEO] != NULL) {
2741        // if we had video channel before, delete it first
2742        delete m_channels[QCAMERA_CH_TYPE_VIDEO];
2743        m_channels[QCAMERA_CH_TYPE_VIDEO] = NULL;
2744    }
2745
2746    pChannel = new QCameraVideoChannel(mCameraHandle->camera_handle,
2747                                       mCameraHandle->ops);
2748    if (NULL == pChannel) {
2749        ALOGE("%s: no mem for video channel", __func__);
2750        return NO_MEMORY;
2751    }
2752
2753    // preview only channel, don't need bundle attr and cb
2754    rc = pChannel->init(NULL, NULL, NULL);
2755    if (rc != 0) {
2756        ALOGE("%s: init video channel failed, ret = %d", __func__, rc);
2757        delete pChannel;
2758        return rc;
2759    }
2760
2761    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_VIDEO,
2762                            video_stream_cb_routine, this);
2763    if (rc != NO_ERROR) {
2764        ALOGE("%s: add video stream failed, ret = %d", __func__, rc);
2765        delete pChannel;
2766        return rc;
2767    }
2768
2769    m_channels[QCAMERA_CH_TYPE_VIDEO] = pChannel;
2770    return rc;
2771}
2772
2773/*===========================================================================
2774 * FUNCTION   : addSnapshotChannel
2775 *
2776 * DESCRIPTION: add a snapshot channel that contains a snapshot stream
2777 *
2778 * PARAMETERS : none
2779 *
2780 * RETURN     : int32_t type of status
2781 *              NO_ERROR  -- success
2782 *              none-zero failure code
2783 * NOTE       : Add this channel for live snapshot usecase. Regular capture will
2784 *              use addCaptureChannel.
2785 *==========================================================================*/
2786int32_t QCamera2HardwareInterface::addSnapshotChannel()
2787{
2788    int32_t rc = NO_ERROR;
2789    QCameraChannel *pChannel = NULL;
2790
2791    if (m_channels[QCAMERA_CH_TYPE_SNAPSHOT] != NULL) {
2792        // if we had ZSL channel before, delete it first
2793        delete m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
2794        m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = NULL;
2795    }
2796
2797    pChannel = new QCameraChannel(mCameraHandle->camera_handle,
2798                                  mCameraHandle->ops);
2799    if (NULL == pChannel) {
2800        ALOGE("%s: no mem for snapshot channel", __func__);
2801        return NO_MEMORY;
2802    }
2803
2804    rc = pChannel->init(NULL, NULL, NULL);
2805    if (rc != NO_ERROR) {
2806        ALOGE("%s: init snapshot channel failed, ret = %d", __func__, rc);
2807        delete pChannel;
2808        return rc;
2809    }
2810
2811    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
2812                            snapshot_stream_cb_routine, this);
2813    if (rc != NO_ERROR) {
2814        ALOGE("%s: add snapshot stream failed, ret = %d", __func__, rc);
2815        delete pChannel;
2816        return rc;
2817    }
2818
2819    m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = pChannel;
2820    return rc;
2821}
2822
2823/*===========================================================================
2824 * FUNCTION   : addRawChannel
2825 *
2826 * DESCRIPTION: add a raw channel that contains a raw image stream
2827 *
2828 * PARAMETERS : none
2829 *
2830 * RETURN     : int32_t type of status
2831 *              NO_ERROR  -- success
2832 *              none-zero failure code
2833 *==========================================================================*/
2834int32_t QCamera2HardwareInterface::addRawChannel()
2835{
2836    int32_t rc = NO_ERROR;
2837    QCameraChannel *pChannel = NULL;
2838
2839    if (m_channels[QCAMERA_CH_TYPE_RAW] != NULL) {
2840        // if we had raw channel before, delete it first
2841        delete m_channels[QCAMERA_CH_TYPE_RAW];
2842        m_channels[QCAMERA_CH_TYPE_RAW] = NULL;
2843    }
2844
2845    pChannel = new QCameraChannel(mCameraHandle->camera_handle,
2846                                  mCameraHandle->ops);
2847    if (NULL == pChannel) {
2848        ALOGE("%s: no mem for raw channel", __func__);
2849        return NO_MEMORY;
2850    }
2851
2852    rc = pChannel->init(NULL, NULL, NULL);
2853    if (rc != NO_ERROR) {
2854        ALOGE("%s: init raw channel failed, ret = %d", __func__, rc);
2855        delete pChannel;
2856        return rc;
2857    }
2858
2859    // meta data stream always coexists with snapshot in regular RAW capture case
2860    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
2861                            metadata_stream_cb_routine, this);
2862    if (rc != NO_ERROR) {
2863        ALOGE("%s: add metadata stream failed, ret = %d", __func__, rc);
2864        delete pChannel;
2865        return rc;
2866    }
2867
2868    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
2869                            raw_stream_cb_routine, this);
2870    if (rc != NO_ERROR) {
2871        ALOGE("%s: add snapshot stream failed, ret = %d", __func__, rc);
2872        delete pChannel;
2873        return rc;
2874    }
2875
2876    m_channels[QCAMERA_CH_TYPE_RAW] = pChannel;
2877    return rc;
2878}
2879
2880/*===========================================================================
2881 * FUNCTION   : addZSLChannel
2882 *
2883 * DESCRIPTION: add a ZSL channel that contains a preview stream and
2884 *              a snapshot stream
2885 *
2886 * PARAMETERS : none
2887 *
2888 * RETURN     : int32_t type of status
2889 *              NO_ERROR  -- success
2890 *              none-zero failure code
2891 *==========================================================================*/
2892int32_t QCamera2HardwareInterface::addZSLChannel()
2893{
2894    int32_t rc = NO_ERROR;
2895    QCameraPicChannel *pChannel = NULL;
2896
2897    if (m_channels[QCAMERA_CH_TYPE_ZSL] != NULL) {
2898        // if we had ZSL channel before, delete it first
2899        delete m_channels[QCAMERA_CH_TYPE_ZSL];
2900        m_channels[QCAMERA_CH_TYPE_ZSL] = NULL;
2901    }
2902
2903    pChannel = new QCameraPicChannel(mCameraHandle->camera_handle,
2904                                     mCameraHandle->ops);
2905    if (NULL == pChannel) {
2906        ALOGE("%s: no mem for ZSL channel", __func__);
2907        return NO_MEMORY;
2908    }
2909
2910    // ZSL channel, init with bundle attr and cb
2911    mm_camera_channel_attr_t attr;
2912    memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
2913    attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
2914    attr.look_back = mParameters.getZSLBackLookCount();
2915    attr.post_frame_skip = mParameters.getZSLBurstInterval();
2916    attr.water_mark = mParameters.getZSLQueueDepth();
2917    attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
2918    rc = pChannel->init(&attr,
2919                        zsl_channel_cb,
2920                        this);
2921    if (rc != 0) {
2922        ALOGE("%s: init ZSL channel failed, ret = %d", __func__, rc);
2923        delete pChannel;
2924        return rc;
2925    }
2926
2927    // meta data stream always coexists with preview if applicable
2928    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
2929                            metadata_stream_cb_routine, this);
2930    if (rc != NO_ERROR) {
2931        ALOGE("%s: add metadata stream failed, ret = %d", __func__, rc);
2932        delete pChannel;
2933        return rc;
2934    }
2935
2936    if (isNoDisplayMode()) {
2937        rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
2938                                nodisplay_preview_stream_cb_routine, this);
2939    } else {
2940        rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
2941                                preview_stream_cb_routine, this);
2942    }
2943    if (rc != NO_ERROR) {
2944        ALOGE("%s: add preview stream failed, ret = %d", __func__, rc);
2945        delete pChannel;
2946        return rc;
2947    }
2948
2949    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
2950                            NULL, this);
2951    if (rc != NO_ERROR) {
2952        ALOGE("%s: add snapshot stream failed, ret = %d", __func__, rc);
2953        delete pChannel;
2954        return rc;
2955    }
2956
2957    m_channels[QCAMERA_CH_TYPE_ZSL] = pChannel;
2958    return rc;
2959}
2960
2961/*===========================================================================
2962 * FUNCTION   : addCaptureChannel
2963 *
2964 * DESCRIPTION: add a capture channel that contains a snapshot stream
2965 *              and a postview stream
2966 *
2967 * PARAMETERS : none
2968 *
2969 * RETURN     : int32_t type of status
2970 *              NO_ERROR  -- success
2971 *              none-zero failure code
2972 * NOTE       : Add this channel for regular capture usecase.
2973 *              For Live snapshot usecase, use addSnapshotChannel.
2974 *==========================================================================*/
2975int32_t QCamera2HardwareInterface::addCaptureChannel()
2976{
2977    int32_t rc = NO_ERROR;
2978    QCameraChannel *pChannel = NULL;
2979
2980    if (m_channels[QCAMERA_CH_TYPE_CAPTURE] != NULL) {
2981        delete m_channels[QCAMERA_CH_TYPE_CAPTURE];
2982        m_channels[QCAMERA_CH_TYPE_CAPTURE] = NULL;
2983    }
2984
2985    pChannel = new QCameraChannel(mCameraHandle->camera_handle,
2986                                  mCameraHandle->ops);
2987    if (NULL == pChannel) {
2988        ALOGE("%s: no mem for capture channel", __func__);
2989        return NO_MEMORY;
2990    }
2991
2992    // Capture channel, only need snapshot and postview streams start together
2993    mm_camera_channel_attr_t attr;
2994    memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
2995    attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
2996    attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
2997
2998    rc = pChannel->init(&attr,
2999                        capture_channel_cb_routine,
3000                        this);
3001    if (rc != NO_ERROR) {
3002        ALOGE("%s: init capture channel failed, ret = %d", __func__, rc);
3003        delete pChannel;
3004        return rc;
3005    }
3006
3007
3008    // meta data stream always coexists with snapshot in regular capture case
3009    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
3010                            metadata_stream_cb_routine, this);
3011    if (rc != NO_ERROR) {
3012        ALOGE("%s: add metadata stream failed, ret = %d", __func__, rc);
3013        delete pChannel;
3014        return rc;
3015    }
3016
3017    // TODO: commented out for now
3018#if 0
3019    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_POSTVIEW,
3020                            postview_stream_cb_routine, this);
3021
3022    if (rc != NO_ERROR) {
3023        ALOGE("%s: add postview stream failed, ret = %d", __func__, rc);
3024        delete pChannel;
3025        return rc;
3026    }
3027#endif
3028
3029    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
3030                            NULL, this);
3031    if (rc != NO_ERROR) {
3032        ALOGE("%s: add snapshot stream failed, ret = %d", __func__, rc);
3033        delete pChannel;
3034        return rc;
3035    }
3036
3037    m_channels[QCAMERA_CH_TYPE_CAPTURE] = pChannel;
3038    return rc;
3039}
3040
3041/*===========================================================================
3042 * FUNCTION   : addMetaDataChannel
3043 *
3044 * DESCRIPTION: add a meta data channel that contains a metadata stream
3045 *
3046 * PARAMETERS : none
3047 *
3048 * RETURN     : int32_t type of status
3049 *              NO_ERROR  -- success
3050 *              none-zero failure code
3051 *==========================================================================*/
3052int32_t QCamera2HardwareInterface::addMetaDataChannel()
3053{
3054    int32_t rc = NO_ERROR;
3055    QCameraChannel *pChannel = NULL;
3056
3057    if (m_channels[QCAMERA_CH_TYPE_METADATA] != NULL) {
3058        delete m_channels[QCAMERA_CH_TYPE_METADATA];
3059        m_channels[QCAMERA_CH_TYPE_METADATA] = NULL;
3060    }
3061
3062    pChannel = new QCameraChannel(mCameraHandle->camera_handle,
3063                                  mCameraHandle->ops);
3064    if (NULL == pChannel) {
3065        ALOGE("%s: no mem for metadata channel", __func__);
3066        return NO_MEMORY;
3067    }
3068
3069    rc = pChannel->init(NULL,
3070                        NULL,
3071                        NULL);
3072    if (rc != NO_ERROR) {
3073        ALOGE("%s: init metadata channel failed, ret = %d", __func__, rc);
3074        delete pChannel;
3075        return rc;
3076    }
3077
3078    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
3079                            metadata_stream_cb_routine, this);
3080    if (rc != NO_ERROR) {
3081        ALOGE("%s: add metadata stream failed, ret = %d", __func__, rc);
3082        delete pChannel;
3083        return rc;
3084    }
3085
3086    m_channels[QCAMERA_CH_TYPE_METADATA] = pChannel;
3087    return rc;
3088}
3089
3090/*===========================================================================
3091 * FUNCTION   : addOnlineReprocChannel
3092 *
3093 * DESCRIPTION: add a online reprocess channel that will do reprocess on frames
3094 *              coming from input channel
3095 *
3096 * PARAMETERS :
3097 *   @pInputChannel : ptr to input channel whose frames will be post-processed
3098 *
3099 * RETURN     : Ptr to the newly created channel obj. NULL if failed.
3100 *==========================================================================*/
3101QCameraReprocessChannel *QCamera2HardwareInterface::addOnlineReprocChannel(
3102                                                      QCameraChannel *pInputChannel)
3103{
3104    int32_t rc = NO_ERROR;
3105    QCameraReprocessChannel *pChannel = NULL;
3106
3107    if (pInputChannel == NULL) {
3108        ALOGE("%s: input channel obj is NULL", __func__);
3109        return NULL;
3110    }
3111
3112    pChannel = new QCameraReprocessChannel(mCameraHandle->camera_handle,
3113                                           mCameraHandle->ops);
3114    if (NULL == pChannel) {
3115        ALOGE("%s: no mem for reprocess channel", __func__);
3116        return NULL;
3117    }
3118
3119    // Capture channel, only need snapshot and postview streams start together
3120    mm_camera_channel_attr_t attr;
3121    memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
3122    attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
3123    attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
3124    rc = pChannel->init(&attr,
3125                        postproc_channel_cb_routine,
3126                        this);
3127    if (rc != NO_ERROR) {
3128        ALOGE("%s: init reprocess channel failed, ret = %d", __func__, rc);
3129        delete pChannel;
3130        return NULL;
3131    }
3132
3133    // pp feature config
3134    cam_pp_feature_config_t pp_config;
3135    memset(&pp_config, 0, sizeof(cam_pp_feature_config_t));
3136    if (mParameters.isZSLMode()) {
3137        if (gCamCapability[mCameraId]->min_required_pp_mask & CAM_QCOM_FEATURE_SHARPNESS) {
3138            pp_config.feature_mask |= CAM_QCOM_FEATURE_SHARPNESS;
3139            pp_config.sharpness = mParameters.getInt(QCameraParameters::KEY_QC_SHARPNESS);
3140        }
3141
3142        if (mParameters.isWNREnabled()) {
3143            pp_config.feature_mask |= CAM_QCOM_FEATURE_DENOISE2D;
3144            pp_config.denoise2d.denoise_enable = 1;
3145            pp_config.denoise2d.process_plates = mParameters.getWaveletDenoiseProcessPlate();
3146        }
3147    }
3148    if (needRotationReprocess()) {
3149        pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION;
3150        int rotation = mParameters.getJpegRotation();
3151        if (rotation == 0) {
3152            pp_config.rotation = ROTATE_0;
3153        } else if (rotation == 90) {
3154            pp_config.rotation = ROTATE_90;
3155        } else if (rotation == 180) {
3156            pp_config.rotation = ROTATE_180;
3157        } else if (rotation == 270) {
3158            pp_config.rotation = ROTATE_270;
3159        }
3160    }
3161
3162    uint8_t minStreamBufNum = mParameters.getNumOfSnapshots();
3163    rc = pChannel->addReprocStreamsFromSource(*this,
3164                                              pp_config,
3165                                              pInputChannel,
3166                                              minStreamBufNum,
3167                                              &gCamCapability[mCameraId]->padding_info);
3168    if (rc != NO_ERROR) {
3169        delete pChannel;
3170        return NULL;
3171    }
3172
3173    return pChannel;
3174}
3175
3176/*===========================================================================
3177 * FUNCTION   : addOfflineReprocChannel
3178 *
3179 * DESCRIPTION: add a offline reprocess channel contains one reproc stream,
3180 *              that will do reprocess on frames coming from external images
3181 *
3182 * PARAMETERS :
3183 *   @img_config  : offline reporcess image info
3184 *   @pp_feature  : pp feature config
3185 *
3186 * RETURN     : int32_t type of status
3187 *              NO_ERROR  -- success
3188 *              none-zero failure code
3189 *==========================================================================*/
3190QCameraReprocessChannel *QCamera2HardwareInterface::addOfflineReprocChannel(
3191                                            cam_pp_offline_src_config_t &img_config,
3192                                            cam_pp_feature_config_t &pp_feature,
3193                                            stream_cb_routine stream_cb,
3194                                            void *userdata)
3195{
3196    int32_t rc = NO_ERROR;
3197    QCameraReprocessChannel *pChannel = NULL;
3198
3199    pChannel = new QCameraReprocessChannel(mCameraHandle->camera_handle,
3200                                           mCameraHandle->ops);
3201    if (NULL == pChannel) {
3202        ALOGE("%s: no mem for reprocess channel", __func__);
3203        return NULL;
3204    }
3205
3206    rc = pChannel->init(NULL, NULL, NULL);
3207    if (rc != NO_ERROR) {
3208        ALOGE("%s: init reprocess channel failed, ret = %d", __func__, rc);
3209        delete pChannel;
3210        return NULL;
3211    }
3212
3213    QCameraHeapMemory *pStreamInfo = allocateStreamInfoBuf(CAM_STREAM_TYPE_OFFLINE_PROC);
3214    if (pStreamInfo == NULL) {
3215        ALOGE("%s: no mem for stream info buf", __func__);
3216        delete pChannel;
3217        return NULL;
3218    }
3219
3220    cam_stream_info_t *streamInfoBuf = (cam_stream_info_t *)pStreamInfo->getPtr(0);
3221    memset(streamInfoBuf, 0, sizeof(cam_stream_info_t));
3222    streamInfoBuf->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC;
3223    streamInfoBuf->fmt = img_config.input_fmt;
3224    streamInfoBuf->dim = img_config.input_dim;
3225    streamInfoBuf->buf_planes = img_config.input_buf_planes;
3226    streamInfoBuf->streaming_mode = CAM_STREAMING_MODE_BURST;
3227    streamInfoBuf->num_of_burst = img_config.num_of_bufs;
3228
3229    streamInfoBuf->reprocess_config.pp_type = CAM_OFFLINE_REPROCESS_TYPE;
3230    streamInfoBuf->reprocess_config.offline = img_config;
3231    streamInfoBuf->reprocess_config.pp_feature_config = pp_feature;
3232
3233    rc = pChannel->addStream(*this,
3234                             pStreamInfo, img_config.num_of_bufs,
3235                             &gCamCapability[mCameraId]->padding_info,
3236                             stream_cb, userdata);
3237
3238    if (rc != NO_ERROR) {
3239        ALOGE("%s: add reprocess stream failed, ret = %d", __func__, rc);
3240        pStreamInfo->deallocate();
3241        delete pStreamInfo;
3242        delete pChannel;
3243        return NULL;
3244    }
3245
3246    return pChannel;
3247}
3248
3249/*===========================================================================
3250 * FUNCTION   : addChannel
3251 *
3252 * DESCRIPTION: add a channel by its type
3253 *
3254 * PARAMETERS :
3255 *   @ch_type : channel type
3256 *
3257 * RETURN     : int32_t type of status
3258 *              NO_ERROR  -- success
3259 *              none-zero failure code
3260 *==========================================================================*/
3261int32_t QCamera2HardwareInterface::addChannel(qcamera_ch_type_enum_t ch_type)
3262{
3263    int32_t rc = UNKNOWN_ERROR;
3264    switch (ch_type) {
3265    case QCAMERA_CH_TYPE_ZSL:
3266        rc = addZSLChannel();
3267        break;
3268    case QCAMERA_CH_TYPE_CAPTURE:
3269        rc = addCaptureChannel();
3270        break;
3271    case QCAMERA_CH_TYPE_PREVIEW:
3272        rc = addPreviewChannel();
3273        break;
3274    case QCAMERA_CH_TYPE_VIDEO:
3275        rc = addVideoChannel();
3276        break;
3277    case QCAMERA_CH_TYPE_SNAPSHOT:
3278        rc = addSnapshotChannel();
3279        break;
3280    case QCAMERA_CH_TYPE_RAW:
3281        rc = addRawChannel();
3282        break;
3283    case QCAMERA_CH_TYPE_METADATA:
3284        rc = addMetaDataChannel();
3285        break;
3286    default:
3287        break;
3288    }
3289    return rc;
3290}
3291
3292/*===========================================================================
3293 * FUNCTION   : delChannel
3294 *
3295 * DESCRIPTION: delete a channel by its type
3296 *
3297 * PARAMETERS :
3298 *   @ch_type : channel type
3299 *
3300 * RETURN     : int32_t type of status
3301 *              NO_ERROR  -- success
3302 *              none-zero failure code
3303 *==========================================================================*/
3304int32_t QCamera2HardwareInterface::delChannel(qcamera_ch_type_enum_t ch_type)
3305{
3306    if (m_channels[ch_type] != NULL) {
3307        delete m_channels[ch_type];
3308        m_channels[ch_type] = NULL;
3309    }
3310
3311    return NO_ERROR;
3312}
3313
3314/*===========================================================================
3315 * FUNCTION   : startChannel
3316 *
3317 * DESCRIPTION: start a channel by its type
3318 *
3319 * PARAMETERS :
3320 *   @ch_type : channel type
3321 *
3322 * RETURN     : int32_t type of status
3323 *              NO_ERROR  -- success
3324 *              none-zero failure code
3325 *==========================================================================*/
3326int32_t QCamera2HardwareInterface::startChannel(qcamera_ch_type_enum_t ch_type)
3327{
3328    int32_t rc = UNKNOWN_ERROR;
3329    if (m_channels[ch_type] != NULL) {
3330        rc = m_channels[ch_type]->start(mParameters);
3331    }
3332
3333    return rc;
3334}
3335
3336/*===========================================================================
3337 * FUNCTION   : stopChannel
3338 *
3339 * DESCRIPTION: stop a channel by its type
3340 *
3341 * PARAMETERS :
3342 *   @ch_type : channel type
3343 *
3344 * RETURN     : int32_t type of status
3345 *              NO_ERROR  -- success
3346 *              none-zero failure code
3347 *==========================================================================*/
3348int32_t QCamera2HardwareInterface::stopChannel(qcamera_ch_type_enum_t ch_type)
3349{
3350    int32_t rc = UNKNOWN_ERROR;
3351    if (m_channels[ch_type] != NULL) {
3352        rc = m_channels[ch_type]->stop();
3353    }
3354
3355    return rc;
3356}
3357
3358/*===========================================================================
3359 * FUNCTION   : preparePreview
3360 *
3361 * DESCRIPTION: add channels needed for preview
3362 *
3363 * PARAMETERS : none
3364 *
3365 * RETURN     : int32_t type of status
3366 *              NO_ERROR  -- success
3367 *              none-zero failure code
3368 *==========================================================================*/
3369int32_t QCamera2HardwareInterface::preparePreview()
3370{
3371    int32_t rc = NO_ERROR;
3372
3373    if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() !=true) {
3374        rc = addChannel(QCAMERA_CH_TYPE_ZSL);
3375        if (rc != NO_ERROR) {
3376            return rc;
3377        }
3378    } else {
3379        rc = addChannel(QCAMERA_CH_TYPE_PREVIEW);
3380        if (rc != NO_ERROR) {
3381            return rc;
3382        }
3383
3384        if(mParameters.getRecordingHintValue() == true) {
3385            rc = addChannel(QCAMERA_CH_TYPE_VIDEO);
3386            if (rc != NO_ERROR) {
3387                delChannel(QCAMERA_CH_TYPE_PREVIEW);
3388                return rc;
3389            }
3390            rc = addChannel(QCAMERA_CH_TYPE_SNAPSHOT);
3391            if (rc != NO_ERROR) {
3392                delChannel(QCAMERA_CH_TYPE_METADATA);
3393                delChannel(QCAMERA_CH_TYPE_PREVIEW);
3394                delChannel(QCAMERA_CH_TYPE_VIDEO);
3395            }
3396        }
3397    }
3398
3399    return rc;
3400}
3401
3402/*===========================================================================
3403 * FUNCTION   : unpreparePreview
3404 *
3405 * DESCRIPTION: delete channels for preview
3406 *
3407 * PARAMETERS : none
3408 *
3409 * RETURN     : none
3410 *==========================================================================*/
3411void QCamera2HardwareInterface::unpreparePreview()
3412{
3413    if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() !=true) {
3414        delChannel(QCAMERA_CH_TYPE_ZSL);
3415    } else {
3416        delChannel(QCAMERA_CH_TYPE_PREVIEW);
3417        if(mParameters.getRecordingHintValue() == true) {
3418            delChannel(QCAMERA_CH_TYPE_VIDEO);
3419            delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
3420        }
3421    }
3422}
3423
3424/*===========================================================================
3425 * FUNCTION   : playShutter
3426 *
3427 * DESCRIPTION: send request to play shutter sound
3428 *
3429 * PARAMETERS : none
3430 *
3431 * RETURN     : none
3432 *==========================================================================*/
3433void QCamera2HardwareInterface::playShutter(){
3434     if (mNotifyCb == NULL ||
3435         msgTypeEnabledWithLock(CAMERA_MSG_SHUTTER) == 0){
3436         ALOGV("%s: shutter msg not enabled or NULL cb", __func__);
3437         return;
3438     }
3439
3440     qcamera_callback_argm_t cbArg;
3441     memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
3442     cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK;
3443     cbArg.msg_type = CAMERA_MSG_SHUTTER;
3444     cbArg.ext1 = 0;
3445
3446     if(!m_bShutterSoundPlayed){
3447         cbArg.ext2 = true;
3448         m_cbNotifier.notifyCallback(cbArg);
3449     }
3450     cbArg.ext2 = false;
3451     m_cbNotifier.notifyCallback(cbArg);
3452     m_bShutterSoundPlayed = false;
3453}
3454
3455/*===========================================================================
3456 * FUNCTION   : getChannelByHandle
3457 *
3458 * DESCRIPTION: return a channel by its handle
3459 *
3460 * PARAMETERS :
3461 *   @channelHandle : channel handle
3462 *
3463 * RETURN     : a channel obj if found, NULL if not found
3464 *==========================================================================*/
3465QCameraChannel *QCamera2HardwareInterface::getChannelByHandle(uint32_t channelHandle)
3466{
3467    for(int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
3468        if (m_channels[i] != NULL &&
3469            m_channels[i]->getMyHandle() == channelHandle) {
3470            return m_channels[i];
3471        }
3472    }
3473
3474    return NULL;
3475}
3476
3477/*===========================================================================
3478 * FUNCTION   : processFaceDetectionReuslt
3479 *
3480 * DESCRIPTION: process face detection reuslt
3481 *
3482 * PARAMETERS :
3483 *   @fd_data : ptr to face detection result struct
3484 *
3485 * RETURN     : int32_t type of status
3486 *              NO_ERROR  -- success
3487 *              none-zero failure code
3488 *==========================================================================*/
3489int32_t QCamera2HardwareInterface::processFaceDetectionResult(cam_face_detection_data_t *fd_data)
3490{
3491    if (!mParameters.isFaceDetectionEnabled()) {
3492        ALOGD("%s: FaceDetection not enabled, no ops here", __func__);
3493        return NO_ERROR;
3494    }
3495
3496    if ((NULL == mDataCb) || (msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_METADATA) == 0)) {
3497        ALOGD("%s: prevew metadata msgtype not enabled, no ops here", __func__);
3498        return NO_ERROR;
3499    }
3500
3501    cam_dimension_t display_dim;
3502    mParameters.getStreamDimension(CAM_STREAM_TYPE_PREVIEW, display_dim);
3503    if (display_dim.width <= 0 || display_dim.height <= 0) {
3504        ALOGE("%s: Invalid preview width or height (%d x %d)",
3505              __func__, display_dim.width, display_dim.height);
3506        return UNKNOWN_ERROR;
3507    }
3508
3509    // process face detection result
3510    size_t faceResultSize = sizeof(camera_frame_metadata_t);
3511    faceResultSize += sizeof(camera_face_t) * MAX_ROI;
3512    camera_memory_t *faceResultBuffer = mGetMemory(-1,
3513                                                   faceResultSize,
3514                                                   1,
3515                                                   mCallbackCookie);
3516    if ( NULL == faceResultBuffer ) {
3517        ALOGE("%s: Not enough memory for face result data",
3518              __func__);
3519        return NO_MEMORY;
3520    }
3521
3522    void *faceData = faceResultBuffer->data;
3523    memset(faceData, 0, faceResultSize);
3524    camera_frame_metadata_t *roiData = (camera_frame_metadata_t * ) faceData;
3525    camera_face_t *faces = (camera_face_t *) faceData + sizeof(camera_frame_metadata_t);
3526
3527    roiData->number_of_faces = fd_data->num_faces_detected;
3528    roiData->faces = faces;
3529    if (roiData->number_of_faces > 0) {
3530        for (int i = 0; i < roiData->number_of_faces; i++) {
3531            faces[i].id = fd_data->faces[i].face_id;
3532            faces[i].score = fd_data->faces[i].score;
3533
3534            // left
3535            faces[i].rect[0] =
3536                MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].face_boundary.left, display_dim.width, 2000, -1000);
3537
3538            // top
3539            faces[i].rect[1] =
3540                MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].face_boundary.top, display_dim.height, 2000, -1000);
3541
3542            // right
3543            faces[i].rect[2] = faces[i].rect[0] +
3544                MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].face_boundary.width, display_dim.width, 2000, 0);
3545
3546             // bottom
3547            faces[i].rect[3] = faces[i].rect[1] +
3548                MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].face_boundary.height, display_dim.height, 2000, 0);
3549
3550            // Center of left eye
3551            faces[i].left_eye[0] =
3552                MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].left_eye_center.x, display_dim.width, 2000, -1000);
3553
3554            faces[i].left_eye[1] =
3555                MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].left_eye_center.y, display_dim.height, 2000, -1000);
3556
3557            // Center of right eye
3558            faces[i].right_eye[0] =
3559                MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].right_eye_center.x, display_dim.width, 2000, -1000);
3560
3561            faces[i].right_eye[1] =
3562                MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].right_eye_center.y, display_dim.height, 2000, -1000);
3563
3564            // Center of mouth
3565            faces[i].mouth[0] =
3566                MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].mouth_center.x, display_dim.width, 2000, -1000);
3567
3568            faces[i].mouth[1] =
3569                MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].mouth_center.y, display_dim.height, 2000, -1000);
3570
3571#if 0
3572            faces[i].smile_degree = fd_data->faces[i].smile_degree;
3573            faces[i].smile_score = fd_data->faces[i].smile_confidence;
3574            faces[i].blink_detected = fd_data->faces[i].blink_detected;
3575            faces[i].face_recognised = fd_data->faces[i].face_recognised;
3576            faces[i].gaze_angle = fd_data->faces[i].gaze_angle;
3577
3578            // upscale by 2 to recover from demaen downscaling
3579            faces[i].updown_dir = fd_data->faces[i].updown_dir * 2;
3580            faces[i].leftright_dir = fd_data->faces[i].leftright_dir * 2;
3581            faces[i].roll_dir = fd_data->faces[i].roll_dir * 2;
3582
3583            faces[i].leye_blink = fd_data->faces[i].left_blink;
3584            faces[i].reye_blink = fd_data->faces[i].right_blink;
3585            faces[i].left_right_gaze = fd_data->faces[i].left_right_gaze;
3586            faces[i].top_bottom_gaze = fd_data->faces[i].top_bottom_gaze;
3587#endif
3588
3589        }
3590    }
3591
3592    qcamera_callback_argm_t cbArg;
3593    memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
3594    cbArg.cb_type = QCAMERA_DATA_CALLBACK;
3595    cbArg.msg_type = CAMERA_MSG_PREVIEW_METADATA;
3596    cbArg.data = faceResultBuffer;
3597    cbArg.metadata = roiData;
3598    cbArg.user_data = faceResultBuffer;
3599    cbArg.cookie = this;
3600    cbArg.release_cb = releaseCameraMemory;
3601    m_cbNotifier.notifyCallback(cbArg);
3602
3603    return NO_ERROR;
3604}
3605
3606/*===========================================================================
3607 * FUNCTION   : releaseCameraMemory
3608 *
3609 * DESCRIPTION: releases camera memory objects
3610 *
3611 * PARAMETERS :
3612 *   @data    : buffer to be released
3613 *   @cookie  : context data
3614 *
3615 * RETURN     : None
3616 *==========================================================================*/
3617void QCamera2HardwareInterface::releaseCameraMemory(void *data, void */*cookie*/)
3618{
3619    camera_memory_t *mem = ( camera_memory_t * ) data;
3620    if ( NULL != mem ) {
3621        mem->release(mem);
3622    }
3623}
3624
3625/*===========================================================================
3626 * FUNCTION   : returnStreamBuffer
3627 *
3628 * DESCRIPTION: returns back a stream buffer
3629 *
3630 * PARAMETERS :
3631 *   @data    : buffer to be released
3632 *   @cookie  : context data
3633 *
3634 * RETURN     : None
3635 *==========================================================================*/
3636void QCamera2HardwareInterface::returnStreamBuffer(void *data, void *cookie)
3637{
3638    QCameraStream *stream = ( QCameraStream * ) cookie;
3639    int idx = ( int ) data;
3640    if ( ( NULL != stream )) {
3641        stream->bufDone(idx);
3642    }
3643}
3644
3645/*===========================================================================
3646 * FUNCTION   : processHistogramStats
3647 *
3648 * DESCRIPTION: process histogram stats
3649 *
3650 * PARAMETERS :
3651 *   @hist_data : ptr to histogram stats struct
3652 *
3653 * RETURN     : int32_t type of status
3654 *              NO_ERROR  -- success
3655 *              none-zero failure code
3656 *==========================================================================*/
3657int32_t QCamera2HardwareInterface::processHistogramStats(cam_hist_stats_t &/*stats_data*/)
3658{
3659    if (!mParameters.isHistogramEnabled()) {
3660        ALOGD("%s: Histogram not enabled, no ops here", __func__);
3661        return NO_ERROR;
3662    }
3663
3664    camera_memory_t *histBuffer = mGetMemory(-1,
3665                                             sizeof(cam_histogram_data_t),
3666                                             1,
3667                                             mCallbackCookie);
3668    if ( NULL == histBuffer ) {
3669        ALOGE("%s: Not enough memory for histogram data",
3670              __func__);
3671        return NO_MEMORY;
3672    }
3673
3674    cam_histogram_data_t *pHistData = (cam_histogram_data_t *)histBuffer->data;
3675    if (pHistData == NULL) {
3676        ALOGE("%s: memory data ptr is NULL", __func__);
3677        return UNKNOWN_ERROR;
3678    }
3679
3680
3681    return NO_ERROR;
3682}
3683
3684/*===========================================================================
3685 * FUNCTION   : updateThermalLevel
3686 *
3687 * DESCRIPTION: update thermal level depending on thermal events
3688 *
3689 * PARAMETERS :
3690 *   @level   : thermal level
3691 *
3692 * RETURN     : int32_t type of status
3693 *              NO_ERROR  -- success
3694 *              none-zero failure code
3695 *==========================================================================*/
3696int QCamera2HardwareInterface::updateThermalLevel(
3697            qcamera_thermal_level_enum_t level)
3698{
3699    int ret = NO_ERROR;
3700    cam_fps_range_t adjustedRange;
3701    int minFPS, maxFPS;
3702    qcamera_thermal_mode thermalMode = mParameters.getThermalMode();
3703    enum msm_vfe_frame_skip_pattern skipPattern;
3704
3705    mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
3706
3707    switch(level) {
3708    case QCAMERA_THERMAL_NO_ADJUSTMENT:
3709        {
3710            adjustedRange.min_fps = minFPS/1000.0f;
3711            adjustedRange.max_fps = maxFPS/1000.0f;
3712            skipPattern = NO_SKIP;
3713        }
3714        break;
3715    case QCAMERA_THERMAL_SLIGHT_ADJUSTMENT:
3716        {
3717            adjustedRange.min_fps = minFPS/1000.0f;
3718            adjustedRange.max_fps = (maxFPS / 2 ) / 1000.0f;
3719            if ( adjustedRange.max_fps < adjustedRange.min_fps ) {
3720                adjustedRange.max_fps = adjustedRange.min_fps;
3721            }
3722            skipPattern = EVERY_2FRAME;
3723        }
3724        break;
3725    case QCAMERA_THERMAL_BIG_ADJUSTMENT:
3726        {
3727            adjustedRange.min_fps = minFPS/1000.0f;
3728            adjustedRange.max_fps = adjustedRange.min_fps;
3729            skipPattern = EVERY_4FRAME;
3730        }
3731        break;
3732    case QCAMERA_THERMAL_SHUTDOWN:
3733        {
3734            // Stop Preview?
3735            // Set lowest min FPS for now
3736            adjustedRange.min_fps = minFPS/1000.0f;
3737            adjustedRange.max_fps = minFPS/1000.0f;
3738            for ( int i = 0 ; i < gCamCapability[mCameraId]->fps_ranges_tbl_cnt ; i++ ) {
3739                if ( gCamCapability[mCameraId]->fps_ranges_tbl[i].min_fps < adjustedRange.min_fps ) {
3740                    adjustedRange.min_fps = gCamCapability[mCameraId]->fps_ranges_tbl[i].min_fps;
3741                    adjustedRange.max_fps = adjustedRange.min_fps;
3742                }
3743            }
3744            skipPattern = MAX_SKIP;
3745        }
3746        break;
3747    default:
3748        {
3749            ALOGE("%s: Invalid thermal level %d", __func__, level);
3750            return BAD_VALUE;
3751        }
3752        break;
3753    }
3754
3755    ALOGI("%s: Thermal level %d, FPS range [%3.2f,%3.2f], frameskip %d",
3756          __func__,
3757          level,
3758          adjustedRange.min_fps,
3759          adjustedRange.max_fps,
3760          skipPattern);
3761
3762    if (thermalMode == QCAMERA_THERMAL_ADJUST_FPS)
3763        ret = mParameters.adjustPreviewFpsRange(&adjustedRange);
3764    else if (thermalMode == QCAMERA_THERMAL_ADJUST_FRAMESKIP)
3765        ret = mParameters.setFrameSkip(skipPattern);
3766    else
3767        ALOGE("%s: Incorrect thermal mode %d", __func__, thermalMode);
3768
3769    return ret;
3770
3771}
3772
3773/*===========================================================================
3774 * FUNCTION   : updateParameters
3775 *
3776 * DESCRIPTION: update parameters
3777 *
3778 * PARAMETERS :
3779 *   @parms       : input parameters string
3780 *   @needRestart : output, flag to indicate if preview restart is needed
3781 *
3782 * RETURN     : int32_t type of status
3783 *              NO_ERROR  -- success
3784 *              none-zero failure code
3785 *==========================================================================*/
3786int QCamera2HardwareInterface::updateParameters(const char *parms, bool &needRestart)
3787{
3788    String8 str = String8(parms);
3789    QCameraParameters param(str);
3790    return mParameters.updateParameters(param, needRestart);
3791}
3792
3793/*===========================================================================
3794 * FUNCTION   : commitParameterChanges
3795 *
3796 * DESCRIPTION: commit parameter changes to the backend to take effect
3797 *
3798 * PARAMETERS : none
3799 *
3800 * RETURN     : int32_t type of status
3801 *              NO_ERROR  -- success
3802 *              none-zero failure code
3803 * NOTE       : This function must be called after updateParameters.
3804 *              Otherwise, no change will be passed to backend to take effect.
3805 *==========================================================================*/
3806int QCamera2HardwareInterface::commitParameterChanges()
3807{
3808    int rc = mParameters.commitParameters();
3809    if (rc == NO_ERROR) {
3810        // update number of snapshot based on committed parameters setting
3811        rc = mParameters.setNumOfSnapshot();
3812    }
3813    return rc;
3814}
3815
3816/*===========================================================================
3817 * FUNCTION   : needDebugFps
3818 *
3819 * DESCRIPTION: if fps log info need to be printed out
3820 *
3821 * PARAMETERS : none
3822 *
3823 * RETURN     : true: need print out fps log
3824 *              false: no need to print out fps log
3825 *==========================================================================*/
3826bool QCamera2HardwareInterface::needDebugFps()
3827{
3828    return mParameters.isFpsDebugEnabled();
3829}
3830
3831/*===========================================================================
3832 * FUNCTION   : needReprocess
3833 *
3834 * DESCRIPTION: if reprocess is needed
3835 *
3836 * PARAMETERS : none
3837 *
3838 * RETURN     : true: needed
3839 *              false: no need
3840 *==========================================================================*/
3841bool QCamera2HardwareInterface::needReprocess()
3842{
3843    // TODO: hack here to return false to avoid reprocess
3844    // Need to be enabled after PP is enabled
3845    return false;
3846
3847    if (!mParameters.isJpegPictureFormat()) {
3848        // RAW image, no need to reprocess
3849        return false;
3850    }
3851
3852    if (mParameters.isZSLMode() &&
3853        ((gCamCapability[mCameraId]->min_required_pp_mask > 0) ||
3854         mParameters.isWNREnabled())) {
3855        // TODO: add for ZSL HDR later
3856        // pp module has min requirement for zsl reprocess, or WNR in ZSL mode
3857        ALOGD("%s: need do reprocess for ZSL WNR or min PP reprocess", __func__);
3858        return true;
3859    }
3860
3861    return needRotationReprocess();
3862}
3863
3864/*===========================================================================
3865 * FUNCTION   : needRotationReprocess
3866 *
3867 * DESCRIPTION: if rotation needs to be done by reprocess in pp
3868 *
3869 * PARAMETERS : none
3870 *
3871 * RETURN     : true: needed
3872 *              false: no need
3873 *==========================================================================*/
3874bool QCamera2HardwareInterface::needRotationReprocess()
3875{
3876    // TODO: hack here to return false to avoid reprocess
3877    // Need to be enabled after PP is enabled
3878    return false;
3879
3880    if (!mParameters.isJpegPictureFormat()) {
3881        // RAW image, no need to reprocess
3882        return false;
3883    }
3884
3885    if (mParameters.isZSLMode() &&
3886        (gCamCapability[mCameraId]->qcom_supported_feature_mask & CAM_QCOM_FEATURE_ROTATION) > 0 &&
3887        mParameters.getJpegRotation() > 0) {
3888        // current rotation is not zero, and pp has the capability to process rotation
3889        ALOGD("%s: need do reprocess for rotation", __func__);
3890        return true;
3891    }
3892
3893    return false;
3894}
3895
3896/*===========================================================================
3897 * FUNCTION   : needRotationReprocess
3898 *
3899 * DESCRIPTION: if online rotation needs to be done by cpp
3900 *
3901 * PARAMETERS : none
3902 *
3903 * RETURN     : true: needed
3904 *              false: no need
3905 *==========================================================================*/
3906bool QCamera2HardwareInterface::needOnlineRotation()
3907{
3908    // TODO: hack here to return false to avoid reprocess
3909    // Need to be enabled after PP is enabled
3910    return false;
3911
3912    if (!mParameters.isJpegPictureFormat()) {
3913        // RAW image, no need
3914        return false;
3915    }
3916
3917    if (!mParameters.isZSLMode() &&
3918        (gCamCapability[mCameraId]->qcom_supported_feature_mask & CAM_QCOM_FEATURE_ROTATION) > 0 &&
3919        mParameters.getJpegRotation() > 0) {
3920        // current rotation is not zero, and pp has the capability to process rotation
3921        ALOGD("%s: need do online rotation", __func__);
3922        return true;
3923    }
3924
3925    return false;
3926}
3927
3928/*===========================================================================
3929 * FUNCTION   : getThumbnailSize
3930 *
3931 * DESCRIPTION: get user set thumbnail size
3932 *
3933 * PARAMETERS :
3934 *   @dim     : output of thumbnail dimension
3935 *
3936 * RETURN     : none
3937 *==========================================================================*/
3938void QCamera2HardwareInterface::getThumbnailSize(cam_dimension_t &dim)
3939{
3940    mParameters.getThumbnailSize(&dim.width, &dim.height);
3941}
3942
3943/*===========================================================================
3944 * FUNCTION   : getJpegQuality
3945 *
3946 * DESCRIPTION: get user set jpeg quality
3947 *
3948 * PARAMETERS : none
3949 *
3950 * RETURN     : jpeg quality setting
3951 *==========================================================================*/
3952int QCamera2HardwareInterface::getJpegQuality()
3953{
3954    return mParameters.getJpegQuality();
3955}
3956
3957/*===========================================================================
3958 * FUNCTION   : getJpegRotation
3959 *
3960 * DESCRIPTION: get rotation information to be passed into jpeg encoding
3961 *
3962 * PARAMETERS : none
3963 *
3964 * RETURN     : rotation information
3965 *==========================================================================*/
3966int QCamera2HardwareInterface::getJpegRotation() {
3967    return mParameters.getJpegRotation();
3968}
3969
3970/*===========================================================================
3971 * FUNCTION   : getExifData
3972 *
3973 * DESCRIPTION: get exif data to be passed into jpeg encoding
3974 *
3975 * PARAMETERS : none
3976 *
3977 * RETURN     : exif data from user setting and GPS
3978 *==========================================================================*/
3979QCameraExif *QCamera2HardwareInterface::getExifData()
3980{
3981    QCameraExif *exif = new QCameraExif();
3982    if (exif == NULL) {
3983        ALOGE("%s: No memory for QCameraExif", __func__);
3984        return NULL;
3985    }
3986
3987    int32_t rc = NO_ERROR;
3988    uint32_t count = 0;
3989
3990    // add exif entries
3991    char dateTime[20];
3992    memset(dateTime, 0, sizeof(dateTime));
3993    count = 20;
3994    rc = mParameters.getExifDateTime(dateTime, count);
3995    if(rc == NO_ERROR) {
3996        exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL,
3997                       EXIF_ASCII,
3998                       count,
3999                       (void *)dateTime);
4000    } else {
4001        ALOGE("%s: getExifDateTime failed", __func__);
4002    }
4003
4004    rat_t focalLength;
4005    rc = mParameters.getExifFocalLength(&focalLength);
4006    if (rc == NO_ERROR) {
4007        exif->addEntry(EXIFTAGID_FOCAL_LENGTH,
4008                       EXIF_RATIONAL,
4009                       1,
4010                       (void *)&(focalLength));
4011    } else {
4012        ALOGE("%s: getExifFocalLength failed", __func__);
4013    }
4014
4015    uint16_t isoSpeed = mParameters.getExifIsoSpeed();
4016    exif->addEntry(EXIFTAGID_ISO_SPEED_RATING,
4017                   EXIF_SHORT,
4018                   1,
4019                   (void *)&(isoSpeed));
4020
4021    char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE];
4022    count = 0;
4023    rc = mParameters.getExifGpsProcessingMethod(gpsProcessingMethod, count);
4024    if(rc == NO_ERROR) {
4025        exif->addEntry(EXIFTAGID_GPS_PROCESSINGMETHOD,
4026                       EXIF_ASCII,
4027                       count,
4028                       (void *)gpsProcessingMethod);
4029    } else {
4030        ALOGE("%s: getExifGpsProcessingMethod failed", __func__);
4031    }
4032
4033    rat_t latitude[3];
4034    char latRef[2];
4035    rc = mParameters.getExifLatitude(latitude, latRef);
4036    if(rc == NO_ERROR) {
4037        exif->addEntry(EXIFTAGID_GPS_LATITUDE,
4038                       EXIF_RATIONAL,
4039                       3,
4040                       (void *)latitude);
4041        exif->addEntry(EXIFTAGID_GPS_LATITUDE_REF,
4042                       EXIF_ASCII,
4043                       2,
4044                       (void *)latRef);
4045    } else {
4046        ALOGE("%s: getExifLatitude failed", __func__);
4047    }
4048
4049    rat_t longitude[3];
4050    char lonRef[2];
4051    rc = mParameters.getExifLongitude(longitude, lonRef);
4052    if(rc == NO_ERROR) {
4053        exif->addEntry(EXIFTAGID_GPS_LONGITUDE,
4054                       EXIF_RATIONAL,
4055                       3,
4056                       (void *)longitude);
4057
4058        exif->addEntry(EXIFTAGID_GPS_LONGITUDE_REF,
4059                       EXIF_ASCII,
4060                       2,
4061                       (void *)lonRef);
4062    } else {
4063        ALOGE("%s: getExifLongitude failed", __func__);
4064    }
4065
4066    rat_t altitude;
4067    char altRef;
4068    rc = mParameters.getExifAltitude(&altitude, &altRef);
4069    if(rc == NO_ERROR) {
4070        exif->addEntry(EXIFTAGID_GPS_ALTITUDE,
4071                       EXIF_RATIONAL,
4072                       1,
4073                       (void *)&(altitude));
4074
4075        exif->addEntry(EXIFTAGID_GPS_ALTITUDE_REF,
4076                       EXIF_BYTE,
4077                       1,
4078                       (void *)&altRef);
4079    } else {
4080        ALOGE("%s: getExifAltitude failed", __func__);
4081    }
4082
4083    char gpsDateStamp[20];
4084    rat_t gpsTimeStamp[3];
4085    rc = mParameters.getExifGpsDateTimeStamp(gpsDateStamp, 20, gpsTimeStamp);
4086    if(rc == NO_ERROR) {
4087        exif->addEntry(EXIFTAGID_GPS_DATESTAMP,
4088                       EXIF_ASCII,
4089                       strlen(gpsDateStamp) + 1,
4090                       (void *)gpsDateStamp);
4091
4092        exif->addEntry(EXIFTAGID_GPS_TIMESTAMP,
4093                       EXIF_RATIONAL,
4094                       3,
4095                       (void *)gpsTimeStamp);
4096    } else {
4097        ALOGE("%s: getExifGpsDataTimeStamp failed", __func__);
4098    }
4099
4100    return exif;
4101}
4102
4103/*===========================================================================
4104 * FUNCTION   : setHistogram
4105 *
4106 * DESCRIPTION: set if histogram should be enabled
4107 *
4108 * PARAMETERS :
4109 *   @histogram_en : bool flag if histogram should be enabled
4110 *
4111 * RETURN     : int32_t type of status
4112 *              NO_ERROR  -- success
4113 *              none-zero failure code
4114 *==========================================================================*/
4115int32_t QCamera2HardwareInterface::setHistogram(bool histogram_en)
4116{
4117    return mParameters.setHistogram(histogram_en);
4118}
4119
4120/*===========================================================================
4121 * FUNCTION   : setFaceDetection
4122 *
4123 * DESCRIPTION: set if face detection should be enabled
4124 *
4125 * PARAMETERS :
4126 *   @enabled : bool flag if face detection should be enabled
4127 *
4128 * RETURN     : int32_t type of status
4129 *              NO_ERROR  -- success
4130 *              none-zero failure code
4131 *==========================================================================*/
4132int32_t QCamera2HardwareInterface::setFaceDetection(bool enabled)
4133{
4134    return mParameters.setFaceDetection(enabled);
4135}
4136
4137/*===========================================================================
4138 * FUNCTION   : prepareHardwareForSnapshot
4139 *
4140 * DESCRIPTION: prepare hardware for snapshot, such as LED
4141 *
4142 * PARAMETERS :
4143 *   @afNeeded: flag indicating if Auto Focus needs to be done during preparation
4144 *
4145 * RETURN     : int32_t type of status
4146 *              NO_ERROR  -- success
4147 *              none-zero failure code
4148 *==========================================================================*/
4149int32_t QCamera2HardwareInterface::prepareHardwareForSnapshot(int32_t afNeeded)
4150{
4151    return mCameraHandle->ops->prepare_snapshot(mCameraHandle->camera_handle,
4152                                                afNeeded);
4153}
4154
4155}; // namespace qcamera
4156