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