1 /* Copyright (c) 2012-2014, 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 <stdio.h>
35 #include <stdlib.h>
36 #include <utils/Errors.h>
37 #include <gralloc_priv.h>
38 #include <gui/Surface.h>
39 
40 #include "QCamera2HWI.h"
41 #include "QCameraMem.h"
42 
43 #define MAP_TO_DRIVER_COORDINATE(val, base, scale, offset) (val * scale / base + offset)
44 #define CAMERA_MIN_STREAMING_BUFFERS     3
45 #define EXTRA_ZSL_PREVIEW_STREAM_BUF     2
46 #define CAMERA_MIN_JPEG_ENCODING_BUFFERS 2
47 #define CAMERA_MIN_VIDEO_BUFFERS         9
48 #define CAMERA_LONGSHOT_STAGES           4
49 
50 //This multiplier signifies extra buffers that we need to allocate
51 //for the output of pproc
52 #define CAMERA_PPROC_OUT_BUFFER_MULTIPLIER 2
53 
54 
55 #define HDR_CONFIDENCE_THRESHOLD 0.4
56 
57 namespace qcamera {
58 
59 cam_capability_t *gCamCaps[MM_CAMERA_MAX_NUM_SENSORS];
60 static pthread_mutex_t g_camlock = PTHREAD_MUTEX_INITIALIZER;
61 volatile uint32_t gCamHalLogLevel = 1;
62 
63 camera_device_ops_t QCamera2HardwareInterface::mCameraOps = {
64     set_preview_window:         QCamera2HardwareInterface::set_preview_window,
65     set_callbacks:              QCamera2HardwareInterface::set_CallBacks,
66     enable_msg_type:            QCamera2HardwareInterface::enable_msg_type,
67     disable_msg_type:           QCamera2HardwareInterface::disable_msg_type,
68     msg_type_enabled:           QCamera2HardwareInterface::msg_type_enabled,
69 
70     start_preview:              QCamera2HardwareInterface::start_preview,
71     stop_preview:               QCamera2HardwareInterface::stop_preview,
72     preview_enabled:            QCamera2HardwareInterface::preview_enabled,
73     store_meta_data_in_buffers: QCamera2HardwareInterface::store_meta_data_in_buffers,
74 
75     start_recording:            QCamera2HardwareInterface::start_recording,
76     stop_recording:             QCamera2HardwareInterface::stop_recording,
77     recording_enabled:          QCamera2HardwareInterface::recording_enabled,
78     release_recording_frame:    QCamera2HardwareInterface::release_recording_frame,
79 
80     auto_focus:                 QCamera2HardwareInterface::auto_focus,
81     cancel_auto_focus:          QCamera2HardwareInterface::cancel_auto_focus,
82 
83     take_picture:               QCamera2HardwareInterface::take_picture,
84     cancel_picture:             QCamera2HardwareInterface::cancel_picture,
85 
86     set_parameters:             QCamera2HardwareInterface::set_parameters,
87     get_parameters:             QCamera2HardwareInterface::get_parameters,
88     put_parameters:             QCamera2HardwareInterface::put_parameters,
89     send_command:               QCamera2HardwareInterface::send_command,
90 
91     release:                    QCamera2HardwareInterface::release,
92     dump:                       QCamera2HardwareInterface::dump,
93 };
94 
95 
getEffectValue(const char * effect)96 int32_t QCamera2HardwareInterface::getEffectValue(const char *effect)
97 {
98     uint32_t cnt = 0;
99     while(NULL != QCameraParameters::EFFECT_MODES_MAP[cnt].desc) {
100         if(!strcmp(QCameraParameters::EFFECT_MODES_MAP[cnt].desc, effect)) {
101             return QCameraParameters::EFFECT_MODES_MAP[cnt].val;
102         }
103         cnt++;
104     }
105     return 0;
106 }
107 /*===========================================================================
108  * FUNCTION   : set_preview_window
109  *
110  * DESCRIPTION: set preview window.
111  *
112  * PARAMETERS :
113  *   @device  : ptr to camera device struct
114  *   @window  : window ops table
115  *
116  * RETURN     : int32_t type of status
117  *              NO_ERROR  -- success
118  *              none-zero failure code
119  *==========================================================================*/
set_preview_window(struct camera_device * device,struct preview_stream_ops * window)120 int QCamera2HardwareInterface::set_preview_window(struct camera_device *device,
121         struct preview_stream_ops *window)
122 {
123     int rc = NO_ERROR;
124     QCamera2HardwareInterface *hw =
125         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
126     if (!hw) {
127         ALOGE("%s: NULL camera device", __func__);
128         return BAD_VALUE;
129     }
130 
131     hw->lockAPI();
132     qcamera_api_result_t apiResult;
133     rc = hw->processAPI(QCAMERA_SM_EVT_SET_PREVIEW_WINDOW, (void *)window);
134     if (rc == NO_ERROR) {
135         hw->waitAPIResult(QCAMERA_SM_EVT_SET_PREVIEW_WINDOW, &apiResult);
136         rc = apiResult.status;
137     }
138     hw->unlockAPI();
139 
140     return rc;
141 }
142 
143 /*===========================================================================
144  * FUNCTION   : set_CallBacks
145  *
146  * DESCRIPTION: set callbacks for notify and data
147  *
148  * PARAMETERS :
149  *   @device     : ptr to camera device struct
150  *   @notify_cb  : notify cb
151  *   @data_cb    : data cb
152  *   @data_cb_timestamp  : video data cd with timestamp
153  *   @get_memory : ops table for request gralloc memory
154  *   @user       : user data ptr
155  *
156  * RETURN     : none
157  *==========================================================================*/
set_CallBacks(struct camera_device * device,camera_notify_callback notify_cb,camera_data_callback data_cb,camera_data_timestamp_callback data_cb_timestamp,camera_request_memory get_memory,void * user)158 void QCamera2HardwareInterface::set_CallBacks(struct camera_device *device,
159         camera_notify_callback notify_cb,
160         camera_data_callback data_cb,
161         camera_data_timestamp_callback data_cb_timestamp,
162         camera_request_memory get_memory,
163         void *user)
164 {
165     QCamera2HardwareInterface *hw =
166         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
167     if (!hw) {
168         ALOGE("NULL camera device");
169         return;
170     }
171 
172     qcamera_sm_evt_setcb_payload_t payload;
173     payload.notify_cb = notify_cb;
174     payload.data_cb = data_cb;
175     payload.data_cb_timestamp = data_cb_timestamp;
176     payload.get_memory = get_memory;
177     payload.user = user;
178 
179     hw->lockAPI();
180     qcamera_api_result_t apiResult;
181     int32_t rc = hw->processAPI(QCAMERA_SM_EVT_SET_CALLBACKS, (void *)&payload);
182     if (rc == NO_ERROR) {
183         hw->waitAPIResult(QCAMERA_SM_EVT_SET_CALLBACKS, &apiResult);
184     }
185     hw->unlockAPI();
186 }
187 
188 /*===========================================================================
189  * FUNCTION   : enable_msg_type
190  *
191  * DESCRIPTION: enable certain msg type
192  *
193  * PARAMETERS :
194  *   @device     : ptr to camera device struct
195  *   @msg_type   : msg type mask
196  *
197  * RETURN     : none
198  *==========================================================================*/
enable_msg_type(struct camera_device * device,int32_t msg_type)199 void QCamera2HardwareInterface::enable_msg_type(struct camera_device *device, int32_t msg_type)
200 {
201     QCamera2HardwareInterface *hw =
202         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
203     if (!hw) {
204         ALOGE("NULL camera device");
205         return;
206     }
207     hw->lockAPI();
208     qcamera_api_result_t apiResult;
209     int32_t rc = hw->processAPI(QCAMERA_SM_EVT_ENABLE_MSG_TYPE, (void *)msg_type);
210     if (rc == NO_ERROR) {
211         hw->waitAPIResult(QCAMERA_SM_EVT_ENABLE_MSG_TYPE, &apiResult);
212     }
213     hw->unlockAPI();
214 }
215 
216 /*===========================================================================
217  * FUNCTION   : disable_msg_type
218  *
219  * DESCRIPTION: disable certain msg type
220  *
221  * PARAMETERS :
222  *   @device     : ptr to camera device struct
223  *   @msg_type   : msg type mask
224  *
225  * RETURN     : none
226  *==========================================================================*/
disable_msg_type(struct camera_device * device,int32_t msg_type)227 void QCamera2HardwareInterface::disable_msg_type(struct camera_device *device, int32_t msg_type)
228 {
229     QCamera2HardwareInterface *hw =
230         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
231     if (!hw) {
232         ALOGE("NULL camera device");
233         return;
234     }
235     hw->lockAPI();
236     qcamera_api_result_t apiResult;
237     int32_t rc = hw->processAPI(QCAMERA_SM_EVT_DISABLE_MSG_TYPE, (void *)msg_type);
238     if (rc == NO_ERROR) {
239         hw->waitAPIResult(QCAMERA_SM_EVT_DISABLE_MSG_TYPE, &apiResult);
240     }
241     hw->unlockAPI();
242 }
243 
244 /*===========================================================================
245  * FUNCTION   : msg_type_enabled
246  *
247  * DESCRIPTION: if certain msg type is enabled
248  *
249  * PARAMETERS :
250  *   @device     : ptr to camera device struct
251  *   @msg_type   : msg type mask
252  *
253  * RETURN     : 1 -- enabled
254  *              0 -- not enabled
255  *==========================================================================*/
msg_type_enabled(struct camera_device * device,int32_t msg_type)256 int QCamera2HardwareInterface::msg_type_enabled(struct camera_device *device, int32_t msg_type)
257 {
258     int ret = NO_ERROR;
259     QCamera2HardwareInterface *hw =
260         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
261     if (!hw) {
262         ALOGE("NULL camera device");
263         return BAD_VALUE;
264     }
265     hw->lockAPI();
266     qcamera_api_result_t apiResult;
267     ret = hw->processAPI(QCAMERA_SM_EVT_MSG_TYPE_ENABLED, (void *)msg_type);
268     if (ret == NO_ERROR) {
269         hw->waitAPIResult(QCAMERA_SM_EVT_MSG_TYPE_ENABLED, &apiResult);
270         ret = apiResult.enabled;
271     }
272     hw->unlockAPI();
273 
274    return ret;
275 }
276 
277 /*===========================================================================
278  * FUNCTION   : start_preview
279  *
280  * DESCRIPTION: start preview
281  *
282  * PARAMETERS :
283  *   @device  : ptr to camera device struct
284  *
285  * RETURN     : int32_t type of status
286  *              NO_ERROR  -- success
287  *              none-zero failure code
288  *==========================================================================*/
start_preview(struct camera_device * device)289 int QCamera2HardwareInterface::start_preview(struct camera_device *device)
290 {
291     int ret = NO_ERROR;
292     QCamera2HardwareInterface *hw =
293         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
294     if (!hw) {
295         ALOGE("NULL camera device");
296         return BAD_VALUE;
297     }
298     CDBG_HIGH("[KPI Perf] %s: E PROFILE_START_PREVIEW", __func__);
299     hw->lockAPI();
300     qcamera_api_result_t apiResult;
301     qcamera_sm_evt_enum_t evt = QCAMERA_SM_EVT_START_PREVIEW;
302     if (hw->isNoDisplayMode()) {
303         evt = QCAMERA_SM_EVT_START_NODISPLAY_PREVIEW;
304     }
305     ret = hw->processAPI(evt, NULL);
306     if (ret == NO_ERROR) {
307         hw->waitAPIResult(evt, &apiResult);
308         ret = apiResult.status;
309     }
310     hw->unlockAPI();
311     hw->m_bPreviewStarted = true;
312     CDBG_HIGH("[KPI Perf] %s: X", __func__);
313     return ret;
314 }
315 
316 /*===========================================================================
317  * FUNCTION   : stop_preview
318  *
319  * DESCRIPTION: stop preview
320  *
321  * PARAMETERS :
322  *   @device  : ptr to camera device struct
323  *
324  * RETURN     : none
325  *==========================================================================*/
stop_preview(struct camera_device * device)326 void QCamera2HardwareInterface::stop_preview(struct camera_device *device)
327 {
328     QCamera2HardwareInterface *hw =
329         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
330     if (!hw) {
331         ALOGE("NULL camera device");
332         return;
333     }
334     CDBG_HIGH("[KPI Perf] %s: E PROFILE_STOP_PREVIEW", __func__);
335     hw->lockAPI();
336     qcamera_api_result_t apiResult;
337     int32_t ret = hw->processAPI(QCAMERA_SM_EVT_STOP_PREVIEW, NULL);
338     if (ret == NO_ERROR) {
339         hw->waitAPIResult(QCAMERA_SM_EVT_STOP_PREVIEW, &apiResult);
340     }
341     hw->unlockAPI();
342     CDBG_HIGH("[KPI Perf] %s: X", __func__);
343 }
344 
345 /*===========================================================================
346  * FUNCTION   : preview_enabled
347  *
348  * DESCRIPTION: if preview is running
349  *
350  * PARAMETERS :
351  *   @device  : ptr to camera device struct
352  *
353  * RETURN     : 1 -- running
354  *              0 -- not running
355  *==========================================================================*/
preview_enabled(struct camera_device * device)356 int QCamera2HardwareInterface::preview_enabled(struct camera_device *device)
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     qcamera_api_result_t apiResult;
368     ret = hw->processAPI(QCAMERA_SM_EVT_PREVIEW_ENABLED, NULL);
369     if (ret == NO_ERROR) {
370         hw->waitAPIResult(QCAMERA_SM_EVT_PREVIEW_ENABLED, &apiResult);
371         ret = apiResult.enabled;
372     }
373     hw->unlockAPI();
374 
375     return ret;
376 }
377 
378 /*===========================================================================
379  * FUNCTION   : store_meta_data_in_buffers
380  *
381  * DESCRIPTION: if need to store meta data in buffers for video frame
382  *
383  * PARAMETERS :
384  *   @device  : ptr to camera device struct
385  *   @enable  : flag if enable
386  *
387  * RETURN     : int32_t type of status
388  *              NO_ERROR  -- success
389  *              none-zero failure code
390  *==========================================================================*/
store_meta_data_in_buffers(struct camera_device * device,int enable)391 int QCamera2HardwareInterface::store_meta_data_in_buffers(
392                 struct camera_device *device, int enable)
393 {
394     int ret = NO_ERROR;
395     QCamera2HardwareInterface *hw =
396         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
397     if (!hw) {
398         ALOGE("NULL camera device");
399         return BAD_VALUE;
400     }
401 
402     hw->lockAPI();
403     qcamera_api_result_t apiResult;
404     ret = hw->processAPI(QCAMERA_SM_EVT_STORE_METADATA_IN_BUFS, (void *)enable);
405     if (ret == NO_ERROR) {
406         hw->waitAPIResult(QCAMERA_SM_EVT_STORE_METADATA_IN_BUFS, &apiResult);
407         ret = apiResult.status;
408     }
409     hw->unlockAPI();
410 
411     return ret;
412 }
413 
414 /*===========================================================================
415  * FUNCTION   : start_recording
416  *
417  * DESCRIPTION: start recording
418  *
419  * PARAMETERS :
420  *   @device  : ptr to camera device struct
421  *
422  * RETURN     : int32_t type of status
423  *              NO_ERROR  -- success
424  *              none-zero failure code
425  *==========================================================================*/
start_recording(struct camera_device * device)426 int QCamera2HardwareInterface::start_recording(struct camera_device *device)
427 {
428     int ret = NO_ERROR;
429     QCamera2HardwareInterface *hw =
430         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
431     if (!hw) {
432         ALOGE("NULL camera device");
433         return BAD_VALUE;
434     }
435     CDBG_HIGH("[KPI Perf] %s: E PROFILE_START_RECORDING", __func__);
436     hw->lockAPI();
437     qcamera_api_result_t apiResult;
438     ret = hw->processAPI(QCAMERA_SM_EVT_START_RECORDING, NULL);
439     if (ret == NO_ERROR) {
440         hw->waitAPIResult(QCAMERA_SM_EVT_START_RECORDING, &apiResult);
441         ret = apiResult.status;
442     }
443     hw->unlockAPI();
444     hw->m_bRecordStarted = true;
445     CDBG_HIGH("[KPI Perf] %s: X", __func__);
446     return ret;
447 }
448 
449 /*===========================================================================
450  * FUNCTION   : stop_recording
451  *
452  * DESCRIPTION: stop recording
453  *
454  * PARAMETERS :
455  *   @device  : ptr to camera device struct
456  *
457  * RETURN     : none
458  *==========================================================================*/
stop_recording(struct camera_device * device)459 void QCamera2HardwareInterface::stop_recording(struct camera_device *device)
460 {
461     QCamera2HardwareInterface *hw =
462         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
463     if (!hw) {
464         ALOGE("NULL camera device");
465         return;
466     }
467     CDBG_HIGH("[KPI Perf] %s: E PROFILE_STOP_RECORDING", __func__);
468     hw->lockAPI();
469     qcamera_api_result_t apiResult;
470     int32_t ret = hw->processAPI(QCAMERA_SM_EVT_STOP_RECORDING, NULL);
471     if (ret == NO_ERROR) {
472         hw->waitAPIResult(QCAMERA_SM_EVT_STOP_RECORDING, &apiResult);
473     }
474     hw->unlockAPI();
475     CDBG_HIGH("[KPI Perf] %s: X", __func__);
476 }
477 
478 /*===========================================================================
479  * FUNCTION   : recording_enabled
480  *
481  * DESCRIPTION: if recording is running
482  *
483  * PARAMETERS :
484  *   @device  : ptr to camera device struct
485  *
486  * RETURN     : 1 -- running
487  *              0 -- not running
488  *==========================================================================*/
recording_enabled(struct camera_device * device)489 int QCamera2HardwareInterface::recording_enabled(struct camera_device *device)
490 {
491     int ret = NO_ERROR;
492     QCamera2HardwareInterface *hw =
493         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
494     if (!hw) {
495         ALOGE("NULL camera device");
496         return BAD_VALUE;
497     }
498     hw->lockAPI();
499     qcamera_api_result_t apiResult;
500     ret = hw->processAPI(QCAMERA_SM_EVT_RECORDING_ENABLED, NULL);
501     if (ret == NO_ERROR) {
502         hw->waitAPIResult(QCAMERA_SM_EVT_RECORDING_ENABLED, &apiResult);
503         ret = apiResult.enabled;
504     }
505     hw->unlockAPI();
506 
507     return ret;
508 }
509 
510 /*===========================================================================
511  * FUNCTION   : release_recording_frame
512  *
513  * DESCRIPTION: return recording frame back
514  *
515  * PARAMETERS :
516  *   @device  : ptr to camera device struct
517  *   @opaque  : ptr to frame to be returned
518  *
519  * RETURN     : none
520  *==========================================================================*/
release_recording_frame(struct camera_device * device,const void * opaque)521 void QCamera2HardwareInterface::release_recording_frame(
522             struct camera_device *device, const void *opaque)
523 {
524     QCamera2HardwareInterface *hw =
525         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
526     if (!hw) {
527         ALOGE("NULL camera device");
528         return;
529     }
530     CDBG_HIGH("%s: E", __func__);
531     hw->lockAPI();
532     qcamera_api_result_t apiResult;
533     int32_t ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, (void *)opaque);
534     if (ret == NO_ERROR) {
535         hw->waitAPIResult(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, &apiResult);
536     }
537     hw->unlockAPI();
538     CDBG_HIGH("%s: X", __func__);
539 }
540 
541 /*===========================================================================
542  * FUNCTION   : auto_focus
543  *
544  * DESCRIPTION: start auto focus
545  *
546  * PARAMETERS :
547  *   @device  : ptr to camera device struct
548  *
549  * RETURN     : int32_t type of status
550  *              NO_ERROR  -- success
551  *              none-zero failure code
552  *==========================================================================*/
auto_focus(struct camera_device * device)553 int QCamera2HardwareInterface::auto_focus(struct camera_device *device)
554 {
555     int ret = NO_ERROR;
556     QCamera2HardwareInterface *hw =
557         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
558     if (!hw) {
559         ALOGE("NULL camera device");
560         return BAD_VALUE;
561     }
562     CDBG_HIGH("[KPI Perf] %s : E PROFILE_AUTO_FOCUS", __func__);
563     hw->lockAPI();
564     qcamera_api_result_t apiResult;
565     ret = hw->processAPI(QCAMERA_SM_EVT_START_AUTO_FOCUS, NULL);
566     if (ret == NO_ERROR) {
567         hw->waitAPIResult(QCAMERA_SM_EVT_START_AUTO_FOCUS, &apiResult);
568         ret = apiResult.status;
569     }
570     hw->unlockAPI();
571     CDBG_HIGH("[KPI Perf] %s : X", __func__);
572 
573     return ret;
574 }
575 
576 /*===========================================================================
577  * FUNCTION   : cancel_auto_focus
578  *
579  * DESCRIPTION: cancel auto focus
580  *
581  * PARAMETERS :
582  *   @device  : ptr to camera device struct
583  *
584  * RETURN     : int32_t type of status
585  *              NO_ERROR  -- success
586  *              none-zero failure code
587  *==========================================================================*/
cancel_auto_focus(struct camera_device * device)588 int QCamera2HardwareInterface::cancel_auto_focus(struct camera_device *device)
589 {
590     int ret = NO_ERROR;
591     QCamera2HardwareInterface *hw =
592         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
593     if (!hw) {
594         ALOGE("NULL camera device");
595         return BAD_VALUE;
596     }
597     ALOGE("[KPI Perf] %s : E PROFILE_CANCEL_AUTO_FOCUS", __func__);
598     hw->lockAPI();
599     qcamera_api_result_t apiResult;
600     ret = hw->processAPI(QCAMERA_SM_EVT_STOP_AUTO_FOCUS, NULL);
601     if (ret == NO_ERROR) {
602         hw->waitAPIResult(QCAMERA_SM_EVT_STOP_AUTO_FOCUS, &apiResult);
603         ret = apiResult.status;
604     }
605     hw->unlockAPI();
606     CDBG_HIGH("[KPI Perf] %s : X", __func__);
607     return ret;
608 }
609 
610 /*===========================================================================
611  * FUNCTION   : take_picture
612  *
613  * DESCRIPTION: take picture
614  *
615  * PARAMETERS :
616  *   @device  : ptr to camera device struct
617  *
618  * RETURN     : int32_t type of status
619  *              NO_ERROR  -- success
620  *              none-zero failure code
621  *==========================================================================*/
take_picture(struct camera_device * device)622 int QCamera2HardwareInterface::take_picture(struct camera_device *device)
623 {
624     int ret = NO_ERROR;
625     QCamera2HardwareInterface *hw =
626         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
627     if (!hw) {
628         ALOGE("NULL camera device");
629         return BAD_VALUE;
630     }
631     CDBG_HIGH("[KPI Perf] %s: E PROFILE_TAKE_PICTURE", __func__);
632     hw->lockAPI();
633     qcamera_api_result_t apiResult;
634 
635    /** Added support for Retro-active Frames:
636      *  takePicture() is called before preparing Snapshot to indicate the
637      *  mm-camera-channel to pick up legacy frames even
638      *  before LED estimation is triggered.
639      */
640 
641     CDBG_HIGH("%s: [ZSL Retro]: numRetroSnap %d, isLiveSnap %d, isZSL %d, isHDR %d",
642        __func__, hw->mParameters.getNumOfRetroSnapshots(),
643        hw->isLiveSnapshot(), hw->isZSLMode(), hw->isHDRMode());
644 
645     // Check for Retro-active Frames
646     if ((hw->mParameters.getNumOfRetroSnapshots() > 0) &&
647         !hw->isLiveSnapshot() && hw->isZSLMode() &&
648         !hw->isHDRMode() && !hw->isLongshotEnabled()) {
649         // Set Retro Picture Mode
650         hw->setRetroPicture(1);
651         hw->m_bLedAfAecLock = 0;
652         CDBG_HIGH("%s: [ZSL Retro] mode", __func__);
653 
654         /* Call take Picture for total number of snapshots required.
655              This includes the number of retro frames and normal frames */
656         ret = hw->processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL);
657         if (ret == NO_ERROR) {
658           // Wait for retro frames, before calling prepare snapshot
659           CDBG_HIGH("%s:[ZSL Retro] Wait for Retro frames to be done", __func__);
660           hw->waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult);
661             ret = apiResult.status;
662         }
663 
664 
665         // Start Preparing for normal Frames
666         CDBG_HIGH("%s: [ZSL Retro]  Start Prepare Snapshot", __func__);
667         /* Prepare snapshot in case LED needs to be flashed */
668         ret = hw->processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL);
669         if (ret == NO_ERROR) {
670             hw->waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, &apiResult);
671             ret = apiResult.status;
672             CDBG_HIGH("%s: [ZSL Retro] Prep Snapshot done", __func__);
673         }
674     }
675     else {
676         hw->setRetroPicture(0);
677         CDBG_HIGH("%s: [ZSL Retro] Normal Pic Taking Mode", __func__);
678 
679         CDBG_HIGH("%s: [ZSL Retro] Start Prepare Snapshot", __func__);
680         /* Prepare snapshot in case LED needs to be flashed */
681         if (hw->mFlashNeeded == 1 || hw->mParameters.isChromaFlashEnabled()) {
682             // Start Preparing for normal Frames
683             CDBG_HIGH("%s: [ZSL Retro]  Start Prepare Snapshot", __func__);
684             /* Prepare snapshot in case LED needs to be flashed */
685             ret = hw->processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL);
686             if (ret == NO_ERROR) {
687               hw->waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, &apiResult);
688                 ret = apiResult.status;
689                 CDBG_HIGH("%s: [ZSL Retro] Prep Snapshot done", __func__);
690 
691             }
692         }
693         /* Regardless what the result value for prepare_snapshot,
694          * go ahead with capture anyway. Just like the way autofocus
695          * is handled in capture case. */
696         /* capture */
697         CDBG_HIGH("%s: [ZSL Retro] Capturing normal frames", __func__);
698         ret = hw->processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL);
699         if (ret == NO_ERROR) {
700           hw->waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult);
701             ret = apiResult.status;
702         }
703     }
704     hw->unlockAPI();
705     CDBG_HIGH("[KPI Perf] %s: X", __func__);
706     return ret;
707 }
708 
709 /*===========================================================================
710  * FUNCTION   : cancel_picture
711  *
712  * DESCRIPTION: cancel current take picture request
713  *
714  * PARAMETERS :
715  *   @device  : ptr to camera device struct
716  *
717  * RETURN     : int32_t type of status
718  *              NO_ERROR  -- success
719  *              none-zero failure code
720  *==========================================================================*/
cancel_picture(struct camera_device * device)721 int QCamera2HardwareInterface::cancel_picture(struct camera_device *device)
722 {
723     int ret = NO_ERROR;
724     QCamera2HardwareInterface *hw =
725         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
726     if (!hw) {
727         ALOGE("NULL camera device");
728         return BAD_VALUE;
729     }
730     hw->lockAPI();
731     qcamera_api_result_t apiResult;
732     ret = hw->processAPI(QCAMERA_SM_EVT_CANCEL_PICTURE, NULL);
733     if (ret == NO_ERROR) {
734         hw->waitAPIResult(QCAMERA_SM_EVT_CANCEL_PICTURE, &apiResult);
735         ret = apiResult.status;
736     }
737     hw->unlockAPI();
738 
739     return ret;
740 }
741 
742 /*===========================================================================
743  * FUNCTION   : set_parameters
744  *
745  * DESCRIPTION: set camera parameters
746  *
747  * PARAMETERS :
748  *   @device  : ptr to camera device struct
749  *   @parms   : string of packed parameters
750  *
751  * RETURN     : int32_t type of status
752  *              NO_ERROR  -- success
753  *              none-zero failure code
754  *==========================================================================*/
set_parameters(struct camera_device * device,const char * parms)755 int QCamera2HardwareInterface::set_parameters(struct camera_device *device,
756                                               const char *parms)
757 {
758     int ret = NO_ERROR;
759     QCamera2HardwareInterface *hw =
760         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
761     if (!hw) {
762         ALOGE("NULL camera device");
763         return BAD_VALUE;
764     }
765     hw->lockAPI();
766     qcamera_api_result_t apiResult;
767     ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS, (void *)parms);
768     if (ret == NO_ERROR) {
769         hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS, &apiResult);
770         ret = apiResult.status;
771     }
772     hw->unlockAPI();
773 
774     return ret;
775 }
776 
777 /*===========================================================================
778  * FUNCTION   : get_parameters
779  *
780  * DESCRIPTION: query camera parameters
781  *
782  * PARAMETERS :
783  *   @device  : ptr to camera device struct
784  *
785  * RETURN     : packed parameters in a string
786  *==========================================================================*/
get_parameters(struct camera_device * device)787 char* QCamera2HardwareInterface::get_parameters(struct camera_device *device)
788 {
789     char *ret = NULL;
790     QCamera2HardwareInterface *hw =
791         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
792     if (!hw) {
793         ALOGE("NULL camera device");
794         return NULL;
795     }
796     hw->lockAPI();
797     qcamera_api_result_t apiResult;
798     int32_t rc = hw->processAPI(QCAMERA_SM_EVT_GET_PARAMS, NULL);
799     if (rc == NO_ERROR) {
800         hw->waitAPIResult(QCAMERA_SM_EVT_GET_PARAMS, &apiResult);
801         ret = apiResult.params;
802     }
803     hw->unlockAPI();
804 
805     return ret;
806 }
807 
808 /*===========================================================================
809  * FUNCTION   : put_parameters
810  *
811  * DESCRIPTION: return camera parameters string back to HAL
812  *
813  * PARAMETERS :
814  *   @device  : ptr to camera device struct
815  *   @parm    : ptr to parameter string to be returned
816  *
817  * RETURN     : none
818  *==========================================================================*/
put_parameters(struct camera_device * device,char * parm)819 void QCamera2HardwareInterface::put_parameters(struct camera_device *device,
820                                                char *parm)
821 {
822     QCamera2HardwareInterface *hw =
823         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
824     if (!hw) {
825         ALOGE("NULL camera device");
826         return;
827     }
828     hw->lockAPI();
829     qcamera_api_result_t apiResult;
830     int32_t ret = hw->processAPI(QCAMERA_SM_EVT_PUT_PARAMS, (void *)parm);
831     if (ret == NO_ERROR) {
832         hw->waitAPIResult(QCAMERA_SM_EVT_PUT_PARAMS, &apiResult);
833     }
834     hw->unlockAPI();
835 }
836 
837 /*===========================================================================
838  * FUNCTION   : send_command
839  *
840  * DESCRIPTION: command to be executed
841  *
842  * PARAMETERS :
843  *   @device  : ptr to camera device struct
844  *   @cmd     : cmd to be executed
845  *   @arg1    : ptr to optional argument1
846  *   @arg2    : ptr to optional argument2
847  *
848  * RETURN     : int32_t type of status
849  *              NO_ERROR  -- success
850  *              none-zero failure code
851  *==========================================================================*/
send_command(struct camera_device * device,int32_t cmd,int32_t arg1,int32_t arg2)852 int QCamera2HardwareInterface::send_command(struct camera_device *device,
853                                             int32_t cmd,
854                                             int32_t arg1,
855                                             int32_t arg2)
856 {
857     int ret = NO_ERROR;
858     QCamera2HardwareInterface *hw =
859         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
860     if (!hw) {
861         ALOGE("NULL camera device");
862         return BAD_VALUE;
863     }
864 
865     qcamera_sm_evt_command_payload_t payload;
866     memset(&payload, 0, sizeof(qcamera_sm_evt_command_payload_t));
867     payload.cmd = cmd;
868     payload.arg1 = arg1;
869     payload.arg2 = arg2;
870     hw->lockAPI();
871     qcamera_api_result_t apiResult;
872     ret = hw->processAPI(QCAMERA_SM_EVT_SEND_COMMAND, (void *)&payload);
873     if (ret == NO_ERROR) {
874         hw->waitAPIResult(QCAMERA_SM_EVT_SEND_COMMAND, &apiResult);
875         ret = apiResult.status;
876     }
877     hw->unlockAPI();
878 
879     return ret;
880 }
881 
882 /*===========================================================================
883  * FUNCTION   : release
884  *
885  * DESCRIPTION: release camera resource
886  *
887  * PARAMETERS :
888  *   @device  : ptr to camera device struct
889  *
890  * RETURN     : none
891  *==========================================================================*/
release(struct camera_device * device)892 void QCamera2HardwareInterface::release(struct camera_device *device)
893 {
894     QCamera2HardwareInterface *hw =
895         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
896     if (!hw) {
897         ALOGE("NULL camera device");
898         return;
899     }
900     hw->lockAPI();
901     qcamera_api_result_t apiResult;
902     int32_t ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE, NULL);
903     if (ret == NO_ERROR) {
904         hw->waitAPIResult(QCAMERA_SM_EVT_RELEASE, &apiResult);
905     }
906     hw->unlockAPI();
907 }
908 
909 /*===========================================================================
910  * FUNCTION   : dump
911  *
912  * DESCRIPTION: dump camera status
913  *
914  * PARAMETERS :
915  *   @device  : ptr to camera device struct
916  *   @fd      : fd for status to be dumped to
917  *
918  * RETURN     : int32_t type of status
919  *              NO_ERROR  -- success
920  *              none-zero failure code
921  *==========================================================================*/
dump(struct camera_device * device,int fd)922 int QCamera2HardwareInterface::dump(struct camera_device *device, int fd)
923 {
924     int ret = NO_ERROR;
925 
926     //Log level property is read when "adb shell dumpsys media.camera" is
927     //called so that the log level can be controlled without restarting
928     //media server
929     getLogLevel();
930     QCamera2HardwareInterface *hw =
931         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
932     if (!hw) {
933         ALOGE("NULL camera device");
934         return BAD_VALUE;
935     }
936     hw->lockAPI();
937     qcamera_api_result_t apiResult;
938     ret = hw->processAPI(QCAMERA_SM_EVT_DUMP, (void *)fd);
939     if (ret == NO_ERROR) {
940         hw->waitAPIResult(QCAMERA_SM_EVT_DUMP, &apiResult);
941         ret = apiResult.status;
942     }
943     hw->unlockAPI();
944 
945     return ret;
946 }
947 
948 /*===========================================================================
949  * FUNCTION   : close_camera_device
950  *
951  * DESCRIPTION: close camera device
952  *
953  * PARAMETERS :
954  *   @device  : ptr to camera device struct
955  *
956  * RETURN     : int32_t type of status
957  *              NO_ERROR  -- success
958  *              none-zero failure code
959  *==========================================================================*/
close_camera_device(hw_device_t * hw_dev)960 int QCamera2HardwareInterface::close_camera_device(hw_device_t *hw_dev)
961 {
962     int ret = NO_ERROR;
963     CDBG_HIGH("[KPI Perf] %s: E",__func__);
964     QCamera2HardwareInterface *hw =
965         reinterpret_cast<QCamera2HardwareInterface *>(
966             reinterpret_cast<camera_device_t *>(hw_dev)->priv);
967     if (!hw) {
968         ALOGE("%s: NULL camera device", __func__);
969         return BAD_VALUE;
970     }
971     delete hw;
972     CDBG_HIGH("[KPI Perf] %s: X",__func__);
973     return ret;
974 }
975 
976 /*===========================================================================
977  * FUNCTION   : register_face_image
978  *
979  * DESCRIPTION: register a face image into imaging lib for face authenticatio/
980  *              face recognition
981  *
982  * PARAMETERS :
983  *   @device  : ptr to camera device struct
984  *   @img_ptr : ptr to image buffer
985  *   @config  : ptr to config about input image, i.e., format, dimension, and etc.
986  *
987  * RETURN     : >=0 unique ID of face registerd.
988  *              <0  failure.
989  *==========================================================================*/
register_face_image(struct camera_device * device,void * img_ptr,cam_pp_offline_src_config_t * config)990 int QCamera2HardwareInterface::register_face_image(struct camera_device *device,
991                                                    void *img_ptr,
992                                                    cam_pp_offline_src_config_t *config)
993 {
994     int ret = NO_ERROR;
995     QCamera2HardwareInterface *hw =
996         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
997     if (!hw) {
998         ALOGE("NULL camera device");
999         return BAD_VALUE;
1000     }
1001     qcamera_sm_evt_reg_face_payload_t payload;
1002     memset(&payload, 0, sizeof(qcamera_sm_evt_reg_face_payload_t));
1003     payload.img_ptr = img_ptr;
1004     payload.config = config;
1005     hw->lockAPI();
1006     qcamera_api_result_t apiResult;
1007     ret = hw->processAPI(QCAMERA_SM_EVT_REG_FACE_IMAGE, (void *)&payload);
1008     if (ret == NO_ERROR) {
1009         hw->waitAPIResult(QCAMERA_SM_EVT_REG_FACE_IMAGE, &apiResult);
1010         ret = apiResult.handle;
1011     }
1012     hw->unlockAPI();
1013 
1014     return ret;
1015 }
1016 
1017 /*===========================================================================
1018  * FUNCTION   : QCamera2HardwareInterface
1019  *
1020  * DESCRIPTION: constructor of QCamera2HardwareInterface
1021  *
1022  * PARAMETERS :
1023  *   @cameraId  : camera ID
1024  *
1025  * RETURN     : none
1026  *==========================================================================*/
QCamera2HardwareInterface(int cameraId)1027 QCamera2HardwareInterface::QCamera2HardwareInterface(int cameraId)
1028     : mCameraId(cameraId),
1029       mCameraHandle(NULL),
1030       mCameraOpened(false),
1031       mPreviewWindow(NULL),
1032       mMsgEnabled(0),
1033       mStoreMetaDataInFrame(0),
1034       m_stateMachine(this),
1035       m_postprocessor(this),
1036       m_thermalAdapter(QCameraThermalAdapter::getInstance()),
1037       m_cbNotifier(this),
1038       m_bShutterSoundPlayed(false),
1039       m_bPreviewStarted(false),
1040       m_bRecordStarted(false),
1041       m_currentFocusState(CAM_AF_NOT_FOCUSED),
1042       m_pPowerModule(NULL),
1043       mDumpFrmCnt(0),
1044       mDumpSkipCnt(0),
1045       mThermalLevel(QCAMERA_THERMAL_NO_ADJUSTMENT),
1046       m_HDRSceneEnabled(false),
1047       mLongshotEnabled(false),
1048       m_max_pic_width(0),
1049       m_max_pic_height(0),
1050       mLiveSnapshotThread(0),
1051       mFlashNeeded(false),
1052       mCaptureRotation(0),
1053       mIs3ALocked(false),
1054       mZoomLevel(0),
1055       mSnapshotJob(-1),
1056       mPostviewJob(-1),
1057       mMetadataJob(-1),
1058       mReprocJob(-1),
1059       mRawdataJob(-1)
1060 {
1061     getLogLevel();
1062     mCameraDevice.common.tag = HARDWARE_DEVICE_TAG;
1063     mCameraDevice.common.version = HARDWARE_DEVICE_API_VERSION(1, 0);
1064     mCameraDevice.common.close = close_camera_device;
1065     mCameraDevice.ops = &mCameraOps;
1066     mCameraDevice.priv = this;
1067 
1068     pthread_mutex_init(&m_lock, NULL);
1069     pthread_cond_init(&m_cond, NULL);
1070 
1071     m_apiResultList = NULL;
1072 
1073     pthread_mutex_init(&m_evtLock, NULL);
1074     pthread_cond_init(&m_evtCond, NULL);
1075     memset(&m_evtResult, 0, sizeof(qcamera_api_result_t));
1076 
1077     pthread_mutex_init(&m_parm_lock, NULL);
1078 
1079     memset(m_channels, 0, sizeof(m_channels));
1080 
1081 #ifdef HAS_MULTIMEDIA_HINTS
1082     if (hw_get_module(POWER_HARDWARE_MODULE_ID, (const hw_module_t **)&m_pPowerModule)) {
1083         ALOGE("%s: %s module not found", __func__, POWER_HARDWARE_MODULE_ID);
1084     }
1085 #endif
1086 
1087     memset(mDeffOngoingJobs, 0, sizeof(mDeffOngoingJobs));
1088 
1089     mDefferedWorkThread.launch(defferedWorkRoutine, this);
1090     mDefferedWorkThread.sendCmd(CAMERA_CMD_TYPE_START_DATA_PROC, FALSE, FALSE);
1091 }
1092 
1093 /*===========================================================================
1094  * FUNCTION   : ~QCamera2HardwareInterface
1095  *
1096  * DESCRIPTION: destructor of QCamera2HardwareInterface
1097  *
1098  * PARAMETERS : none
1099  *
1100  * RETURN     : none
1101  *==========================================================================*/
~QCamera2HardwareInterface()1102 QCamera2HardwareInterface::~QCamera2HardwareInterface()
1103 {
1104     mDefferedWorkThread.sendCmd(CAMERA_CMD_TYPE_STOP_DATA_PROC, TRUE, TRUE);
1105     mDefferedWorkThread.exit();
1106 
1107     closeCamera();
1108     pthread_mutex_destroy(&m_lock);
1109     pthread_cond_destroy(&m_cond);
1110     pthread_mutex_destroy(&m_evtLock);
1111     pthread_cond_destroy(&m_evtCond);
1112     pthread_mutex_destroy(&m_parm_lock);
1113 }
1114 
1115 /*===========================================================================
1116  * FUNCTION   : openCamera
1117  *
1118  * DESCRIPTION: open camera
1119  *
1120  * PARAMETERS :
1121  *   @hw_device  : double ptr for camera device struct
1122  *
1123  * RETURN     : int32_t type of status
1124  *              NO_ERROR  -- success
1125  *              none-zero failure code
1126  *==========================================================================*/
openCamera(struct hw_device_t ** hw_device)1127 int QCamera2HardwareInterface::openCamera(struct hw_device_t **hw_device)
1128 {
1129     int rc = NO_ERROR;
1130     if (mCameraOpened) {
1131         *hw_device = NULL;
1132         return PERMISSION_DENIED;
1133     }
1134     CDBG_HIGH("[KPI Perf] %s: E PROFILE_OPEN_CAMERA camera id %d",
1135         __func__,mCameraId);
1136     rc = openCamera();
1137     if (rc == NO_ERROR){
1138         *hw_device = &mCameraDevice.common;
1139         if (m_thermalAdapter.init(this) != 0) {
1140           ALOGE("Init thermal adapter failed");
1141         }
1142     }
1143     else
1144         *hw_device = NULL;
1145     return rc;
1146 }
1147 
1148 /*===========================================================================
1149  * FUNCTION   : openCamera
1150  *
1151  * DESCRIPTION: open camera
1152  *
1153  * PARAMETERS : none
1154  *
1155  * RETURN     : int32_t type of status
1156  *              NO_ERROR  -- success
1157  *              none-zero failure code
1158  *==========================================================================*/
openCamera()1159 int QCamera2HardwareInterface::openCamera()
1160 {
1161     int32_t l_curr_width = 0;
1162     int32_t l_curr_height = 0;
1163     m_max_pic_width = 0;
1164     m_max_pic_height = 0;
1165     int i;
1166 
1167     if (mCameraHandle) {
1168         ALOGE("Failure: Camera already opened");
1169         return ALREADY_EXISTS;
1170     }
1171     mCameraHandle = camera_open(mCameraId);
1172     if (!mCameraHandle) {
1173         ALOGE("camera_open failed.");
1174         return UNKNOWN_ERROR;
1175     }
1176     if (NULL == gCamCaps[mCameraId])
1177         initCapabilities(mCameraId,mCameraHandle);
1178 
1179     mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle,
1180                                               camEvtHandle,
1181                                               (void *) this);
1182 
1183     /* get max pic size for jpeg work buf calculation*/
1184     for(i = 0; i < gCamCaps[mCameraId]->picture_sizes_tbl_cnt - 1; i++)
1185     {
1186       l_curr_width = gCamCaps[mCameraId]->picture_sizes_tbl[i].width;
1187       l_curr_height = gCamCaps[mCameraId]->picture_sizes_tbl[i].height;
1188 
1189       if ((l_curr_width * l_curr_height) >
1190         (m_max_pic_width * m_max_pic_height)) {
1191         m_max_pic_width = l_curr_width;
1192         m_max_pic_height = l_curr_height;
1193       }
1194     }
1195 
1196     int32_t rc = m_postprocessor.init(jpegEvtHandle, this);
1197     if (rc != 0) {
1198         ALOGE("Init Postprocessor failed");
1199         mCameraHandle->ops->close_camera(mCameraHandle->camera_handle);
1200         mCameraHandle = NULL;
1201         return UNKNOWN_ERROR;
1202     }
1203 
1204     // update padding info from jpeg
1205     cam_padding_info_t padding_info;
1206     m_postprocessor.getJpegPaddingReq(padding_info);
1207     if (gCamCaps[mCameraId]->padding_info.width_padding < padding_info.width_padding) {
1208         gCamCaps[mCameraId]->padding_info.width_padding = padding_info.width_padding;
1209     }
1210     if (gCamCaps[mCameraId]->padding_info.height_padding < padding_info.height_padding) {
1211         gCamCaps[mCameraId]->padding_info.height_padding = padding_info.height_padding;
1212     }
1213     if (gCamCaps[mCameraId]->padding_info.plane_padding < padding_info.plane_padding) {
1214         gCamCaps[mCameraId]->padding_info.plane_padding = padding_info.plane_padding;
1215     }
1216 
1217     mParameters.init(gCamCaps[mCameraId], mCameraHandle, this, this);
1218 
1219     mCameraOpened = true;
1220 
1221     return NO_ERROR;
1222 }
1223 
1224 /*===========================================================================
1225  * FUNCTION   : closeCamera
1226  *
1227  * DESCRIPTION: close camera
1228  *
1229  * PARAMETERS : none
1230  *
1231  * RETURN     : int32_t type of status
1232  *              NO_ERROR  -- success
1233  *              none-zero failure code
1234  *==========================================================================*/
closeCamera()1235 int QCamera2HardwareInterface::closeCamera()
1236 {
1237     int rc = NO_ERROR;
1238     int i;
1239 
1240     if (!mCameraOpened) {
1241         return NO_ERROR;
1242     }
1243 
1244     pthread_mutex_lock(&m_parm_lock);
1245 
1246     // set open flag to false
1247     mCameraOpened = false;
1248 
1249     // deinit Parameters
1250     mParameters.deinit();
1251 
1252     pthread_mutex_unlock(&m_parm_lock);
1253 
1254     // exit notifier
1255     m_cbNotifier.exit();
1256 
1257     // stop and deinit postprocessor
1258     m_postprocessor.stop();
1259     m_postprocessor.deinit();
1260 
1261     //free all pending api results here
1262     if(m_apiResultList != NULL) {
1263         api_result_list *apiResultList = m_apiResultList;
1264         api_result_list *apiResultListNext;
1265         while (apiResultList != NULL) {
1266             apiResultListNext = apiResultList->next;
1267             free(apiResultList);
1268             apiResultList = apiResultListNext;
1269         }
1270     }
1271 
1272     m_thermalAdapter.deinit();
1273 
1274     // delete all channels if not already deleted
1275     for (i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
1276         if (m_channels[i] != NULL) {
1277             m_channels[i]->stop();
1278             delete m_channels[i];
1279             m_channels[i] = NULL;
1280         }
1281     }
1282 
1283     rc = mCameraHandle->ops->close_camera(mCameraHandle->camera_handle);
1284     mCameraHandle = NULL;
1285 
1286     return rc;
1287 }
1288 
1289 #define DATA_PTR(MEM_OBJ,INDEX) MEM_OBJ->getPtr( INDEX )
1290 
1291 /*===========================================================================
1292  * FUNCTION   : initCapabilities
1293  *
1294  * DESCRIPTION: initialize camera capabilities in static data struct
1295  *
1296  * PARAMETERS :
1297  *   @cameraId  : camera Id
1298  *
1299  * RETURN     : int32_t type of status
1300  *              NO_ERROR  -- success
1301  *              none-zero failure code
1302  *==========================================================================*/
initCapabilities(int cameraId,mm_camera_vtbl_t * cameraHandle)1303 int QCamera2HardwareInterface::initCapabilities(int cameraId,mm_camera_vtbl_t *cameraHandle)
1304 {
1305     int rc = NO_ERROR;
1306     QCameraHeapMemory *capabilityHeap = NULL;
1307 
1308     /* Allocate memory for capability buffer */
1309     capabilityHeap = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
1310     rc = capabilityHeap->allocate(1, sizeof(cam_capability_t), NON_SECURE);
1311     if(rc != OK) {
1312         ALOGE("%s: No memory for cappability", __func__);
1313         goto allocate_failed;
1314     }
1315 
1316     /* Map memory for capability buffer */
1317     memset(DATA_PTR(capabilityHeap,0), 0, sizeof(cam_capability_t));
1318     rc = cameraHandle->ops->map_buf(cameraHandle->camera_handle,
1319                                 CAM_MAPPING_BUF_TYPE_CAPABILITY,
1320                                 capabilityHeap->getFd(0),
1321                                 sizeof(cam_capability_t));
1322     if(rc < 0) {
1323         ALOGE("%s: failed to map capability buffer", __func__);
1324         goto map_failed;
1325     }
1326 
1327     /* Query Capability */
1328     rc = cameraHandle->ops->query_capability(cameraHandle->camera_handle);
1329     if(rc < 0) {
1330         ALOGE("%s: failed to query capability",__func__);
1331         goto query_failed;
1332     }
1333     gCamCaps[cameraId] = (cam_capability_t *)malloc(sizeof(cam_capability_t));
1334     if (!gCamCaps[cameraId]) {
1335         ALOGE("%s: out of memory", __func__);
1336         goto query_failed;
1337     }
1338     memcpy(gCamCaps[cameraId], DATA_PTR(capabilityHeap,0),
1339                                         sizeof(cam_capability_t));
1340 
1341     rc = NO_ERROR;
1342 
1343 query_failed:
1344     cameraHandle->ops->unmap_buf(cameraHandle->camera_handle,
1345                             CAM_MAPPING_BUF_TYPE_CAPABILITY);
1346 map_failed:
1347     capabilityHeap->deallocate();
1348     delete capabilityHeap;
1349 allocate_failed:
1350     return rc;
1351 }
1352 
1353 /*===========================================================================
1354  * FUNCTION   : getCapabilities
1355  *
1356  * DESCRIPTION: query camera capabilities
1357  *
1358  * PARAMETERS :
1359  *   @cameraId  : camera Id
1360  *   @info      : camera info struct to be filled in with camera capabilities
1361  *
1362  * RETURN     : int32_t type of status
1363  *              NO_ERROR  -- success
1364  *              none-zero failure code
1365  *==========================================================================*/
getCapabilities(int cameraId,struct camera_info * info)1366 int QCamera2HardwareInterface::getCapabilities(int cameraId,
1367                                     struct camera_info *info)
1368 {
1369     int rc = NO_ERROR;
1370     struct  camera_info *p_info;
1371     pthread_mutex_lock(&g_camlock);
1372     p_info = get_cam_info(cameraId);
1373     p_info->device_version = CAMERA_DEVICE_API_VERSION_1_0;
1374     p_info->static_camera_characteristics = NULL;
1375     memcpy(info, p_info, sizeof (struct camera_info));
1376     pthread_mutex_unlock(&g_camlock);
1377     return rc;
1378 }
1379 
1380 /*===========================================================================
1381  * FUNCTION   : prepareTorchCamera
1382  *
1383  * DESCRIPTION: initializes the camera ( if needed )
1384  *              so torch can be configured.
1385  *
1386  * PARAMETERS :
1387  *
1388  * RETURN     : int32_t type of status
1389  *              NO_ERROR  -- success
1390  *              none-zero failure code
1391  *==========================================================================*/
prepareTorchCamera()1392 int QCamera2HardwareInterface::prepareTorchCamera()
1393 {
1394     int rc = NO_ERROR;
1395 
1396     if ( ( !m_stateMachine.isPreviewRunning() ) &&
1397             !m_stateMachine.isPreviewReady() &&
1398             ( m_channels[QCAMERA_CH_TYPE_PREVIEW] == NULL ) ) {
1399         rc = addChannel(QCAMERA_CH_TYPE_PREVIEW);
1400     }
1401 
1402     return rc;
1403 }
1404 
1405 /*===========================================================================
1406  * FUNCTION   : releaseTorchCamera
1407  *
1408  * DESCRIPTION: releases all previously acquired camera resources ( if any )
1409  *              needed for torch configuration.
1410  *
1411  * PARAMETERS :
1412  *
1413  * RETURN     : int32_t type of status
1414  *              NO_ERROR  -- success
1415  *              none-zero failure code
1416  *==========================================================================*/
releaseTorchCamera()1417 int QCamera2HardwareInterface::releaseTorchCamera()
1418 {
1419     if ( !m_stateMachine.isPreviewRunning() &&
1420             !m_stateMachine.isPreviewReady() &&
1421             ( m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL ) ) {
1422         delete m_channels[QCAMERA_CH_TYPE_PREVIEW];
1423         m_channels[QCAMERA_CH_TYPE_PREVIEW] = NULL;
1424     }
1425 
1426     return NO_ERROR;
1427 }
1428 
1429 /*===========================================================================
1430  * FUNCTION   : getBufNumRequired
1431  *
1432  * DESCRIPTION: return number of stream buffers needed for given stream type
1433  *
1434  * PARAMETERS :
1435  *   @stream_type  : type of stream
1436  *
1437  * RETURN     : number of buffers needed
1438  *==========================================================================*/
getBufNumRequired(cam_stream_type_t stream_type)1439 uint8_t QCamera2HardwareInterface::getBufNumRequired(cam_stream_type_t stream_type)
1440 {
1441     int bufferCnt = 0;
1442     int minCaptureBuffers = mParameters.getNumOfSnapshots();
1443     char value[PROPERTY_VALUE_MAX];
1444     bool raw_yuv = false;
1445 
1446     int zslQBuffers = mParameters.getZSLQueueDepth();
1447 
1448     int minCircularBufNum = mParameters.getMaxUnmatchedFramesInQueue() +
1449                             CAMERA_MIN_JPEG_ENCODING_BUFFERS;
1450 
1451     int maxStreamBuf = minCaptureBuffers + mParameters.getMaxUnmatchedFramesInQueue() +
1452                        mParameters.getNumOfExtraHDRInBufsIfNeeded() -
1453                        mParameters.getNumOfExtraHDROutBufsIfNeeded() +
1454                        mParameters.getNumOfExtraBuffersForImageProc() +
1455                        EXTRA_ZSL_PREVIEW_STREAM_BUF;
1456 
1457     int minUndequeCount = 0;
1458     if (!isNoDisplayMode()) {
1459         if(mPreviewWindow != NULL) {
1460             if (mPreviewWindow->get_min_undequeued_buffer_count(mPreviewWindow,&minUndequeCount)
1461                 != 0) {
1462                 ALOGE("get_min_undequeued_buffer_count  failed");
1463                 //TODO: hardcoded because MIN_UNDEQUEUED_BUFFERS not defined
1464                 //minUndequeCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS;
1465                 minUndequeCount = 2;
1466             }
1467         } else {
1468             //preview window might not be set at this point. So, query directly
1469             //from BufferQueue implementation of gralloc buffers.
1470             //minUndequeCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS;
1471             //hardcoded because MIN_UNDEQUEUED_BUFFERS not defined. REVISIT
1472             minUndequeCount = 2;
1473         }
1474     }
1475 
1476     // Get buffer count for the particular stream type
1477     switch (stream_type) {
1478     case CAM_STREAM_TYPE_PREVIEW:
1479         {
1480             if (mParameters.isZSLMode()) {
1481                 // We need to add two extra streming buffers to add
1482                 // flexibility in forming matched super buf in ZSL queue.
1483                 // with number being 'zslQBuffers + minCircularBufNum'
1484                 // we see preview buffers sometimes get dropped at CPP
1485                 // and super buf is not forming in ZSL Q for long time.
1486 
1487                 bufferCnt = zslQBuffers + minCircularBufNum +
1488                         mParameters.getNumOfExtraBuffersForImageProc() +
1489                         EXTRA_ZSL_PREVIEW_STREAM_BUF;
1490             } else {
1491                 bufferCnt = CAMERA_MIN_STREAMING_BUFFERS +
1492                             mParameters.getMaxUnmatchedFramesInQueue();
1493             }
1494             bufferCnt += minUndequeCount;
1495         }
1496         break;
1497     case CAM_STREAM_TYPE_POSTVIEW:
1498         {
1499             bufferCnt = minCaptureBuffers*CAMERA_PPROC_OUT_BUFFER_MULTIPLIER +
1500                         mParameters.getNumOfExtraHDRInBufsIfNeeded() -
1501                         mParameters.getNumOfExtraHDROutBufsIfNeeded() +
1502                         mParameters.getNumOfExtraBuffersForImageProc();
1503 
1504             if (bufferCnt > maxStreamBuf) {
1505                 bufferCnt = maxStreamBuf;
1506             }
1507             bufferCnt += minUndequeCount;
1508         }
1509         break;
1510     case CAM_STREAM_TYPE_SNAPSHOT:
1511         {
1512             if (mParameters.isZSLMode() || mLongshotEnabled) {
1513                 if (minCaptureBuffers == 1 && !mLongshotEnabled) {
1514                     // Single ZSL snapshot case
1515                     bufferCnt = zslQBuffers + CAMERA_MIN_STREAMING_BUFFERS +
1516                             mParameters.getNumOfExtraBuffersForImageProc();
1517                 }
1518                 else {
1519                     // ZSL Burst or Longshot case
1520                     bufferCnt = zslQBuffers + minCircularBufNum +
1521                             mParameters.getNumOfExtraBuffersForImageProc();
1522                 }
1523             } else {
1524                 bufferCnt = minCaptureBuffers*CAMERA_PPROC_OUT_BUFFER_MULTIPLIER +
1525                             mParameters.getNumOfExtraHDRInBufsIfNeeded() -
1526                             mParameters.getNumOfExtraHDROutBufsIfNeeded() +
1527                             mParameters.getNumOfExtraBuffersForImageProc();
1528 
1529                 if (bufferCnt > maxStreamBuf) {
1530                     bufferCnt = maxStreamBuf;
1531                 }
1532             }
1533         }
1534         break;
1535     case CAM_STREAM_TYPE_RAW:
1536         property_get("persist.camera.raw_yuv", value, "0");
1537         raw_yuv = atoi(value) > 0 ? true : false;
1538 
1539         if (isRdiMode() || raw_yuv) {
1540             CDBG_HIGH("RDI_DEBUG %s[%d]: CAM_STREAM_TYPE_RAW",
1541               __func__, __LINE__);
1542             bufferCnt = zslQBuffers + minCircularBufNum;
1543         } else if (mParameters.isZSLMode()) {
1544             bufferCnt = zslQBuffers + minCircularBufNum;
1545         } else {
1546             bufferCnt = minCaptureBuffers*CAMERA_PPROC_OUT_BUFFER_MULTIPLIER +
1547                         mParameters.getNumOfExtraHDRInBufsIfNeeded() -
1548                         mParameters.getNumOfExtraHDROutBufsIfNeeded() +
1549                         mParameters.getNumOfExtraBuffersForImageProc();
1550 
1551             if (bufferCnt > maxStreamBuf) {
1552                 bufferCnt = maxStreamBuf;
1553             }
1554         }
1555         break;
1556     case CAM_STREAM_TYPE_VIDEO:
1557         {
1558             bufferCnt = CAMERA_MIN_VIDEO_BUFFERS;
1559         }
1560         break;
1561     case CAM_STREAM_TYPE_METADATA:
1562         {
1563             if (mParameters.isZSLMode()) {
1564                 bufferCnt = zslQBuffers + minCircularBufNum +
1565                             mParameters.getNumOfExtraHDRInBufsIfNeeded() -
1566                             mParameters.getNumOfExtraHDROutBufsIfNeeded() +
1567                             mParameters.getNumOfExtraBuffersForImageProc();
1568             } else {
1569                 bufferCnt = minCaptureBuffers +
1570                             mParameters.getNumOfExtraHDRInBufsIfNeeded() -
1571                             mParameters.getNumOfExtraHDROutBufsIfNeeded() +
1572                             mParameters.getMaxUnmatchedFramesInQueue() +
1573                             CAMERA_MIN_STREAMING_BUFFERS +
1574                             mParameters.getNumOfExtraBuffersForImageProc();
1575 
1576                 if (bufferCnt > zslQBuffers + minCircularBufNum) {
1577                     bufferCnt = zslQBuffers + minCircularBufNum;
1578                 }
1579             }
1580         }
1581         break;
1582     case CAM_STREAM_TYPE_OFFLINE_PROC:
1583         {
1584             bufferCnt = minCaptureBuffers;
1585             if (mLongshotEnabled) {
1586                 bufferCnt = CAMERA_LONGSHOT_STAGES;
1587             }
1588         }
1589         break;
1590     case CAM_STREAM_TYPE_DEFAULT:
1591     case CAM_STREAM_TYPE_MAX:
1592     default:
1593         bufferCnt = 0;
1594         break;
1595     }
1596 
1597     return bufferCnt;
1598 }
1599 
1600 /*===========================================================================
1601  * FUNCTION   : allocateStreamBuf
1602  *
1603  * DESCRIPTION: alocate stream buffers
1604  *
1605  * PARAMETERS :
1606  *   @stream_type  : type of stream
1607  *   @size         : size of buffer
1608  *   @stride       : stride of buffer
1609  *   @scanline     : scanline of buffer
1610  *   @bufferCnt    : [IN/OUT] minimum num of buffers to be allocated.
1611  *                   could be modified during allocation if more buffers needed
1612  *
1613  * RETURN     : ptr to a memory obj that holds stream buffers.
1614  *              NULL if failed
1615  *==========================================================================*/
allocateStreamBuf(cam_stream_type_t stream_type,int size,int stride,int scanline,uint8_t & bufferCnt)1616 QCameraMemory *QCamera2HardwareInterface::allocateStreamBuf(cam_stream_type_t stream_type,
1617                                                             int size,
1618                                                             int stride,
1619                                                             int scanline,
1620                                                             uint8_t &bufferCnt)
1621 {
1622     int rc = NO_ERROR;
1623     QCameraMemory *mem = NULL;
1624     bool bCachedMem = QCAMERA_ION_USE_CACHE;
1625     bool bPoolMem = false;
1626     char value[PROPERTY_VALUE_MAX];
1627     property_get("persist.camera.mem.usepool", value, "1");
1628     if (atoi(value) == 1) {
1629         bPoolMem = true;
1630     }
1631 
1632     // Allocate stream buffer memory object
1633     switch (stream_type) {
1634     case CAM_STREAM_TYPE_PREVIEW:
1635         {
1636             if (isNoDisplayMode()) {
1637                 mem = new QCameraStreamMemory(mGetMemory,
1638                         bCachedMem,
1639                         (bPoolMem) ? &m_memoryPool : NULL,
1640                         stream_type);
1641             } else {
1642                 cam_dimension_t dim;
1643                 QCameraGrallocMemory *grallocMemory =
1644                     new QCameraGrallocMemory(mGetMemory);
1645 
1646                 mParameters.getStreamDimension(stream_type, dim);
1647                 if (grallocMemory)
1648                     grallocMemory->setWindowInfo(mPreviewWindow, dim.width,
1649                         dim.height, stride, scanline,
1650                         mParameters.getPreviewHalPixelFormat());
1651                 mem = grallocMemory;
1652             }
1653         }
1654         break;
1655     case CAM_STREAM_TYPE_POSTVIEW:
1656         {
1657             if (isNoDisplayMode() || isPreviewRestartEnabled()) {
1658                 mem = new QCameraStreamMemory(mGetMemory, bCachedMem);
1659             } else {
1660                 cam_dimension_t dim;
1661                 QCameraGrallocMemory *grallocMemory =
1662                         new QCameraGrallocMemory(mGetMemory);
1663 
1664                 mParameters.getStreamDimension(stream_type, dim);
1665                 if (grallocMemory)
1666                     grallocMemory->setWindowInfo(mPreviewWindow, dim.width,
1667                             dim.height, stride, scanline,
1668                             mParameters.getPreviewHalPixelFormat());
1669                 mem = grallocMemory;
1670             }
1671         }
1672         break;
1673     case CAM_STREAM_TYPE_SNAPSHOT:
1674     case CAM_STREAM_TYPE_RAW:
1675     case CAM_STREAM_TYPE_METADATA:
1676     case CAM_STREAM_TYPE_OFFLINE_PROC:
1677         mem = new QCameraStreamMemory(mGetMemory,
1678                 bCachedMem,
1679                 (bPoolMem) ? &m_memoryPool : NULL,
1680                 stream_type);
1681         break;
1682     case CAM_STREAM_TYPE_VIDEO:
1683         {
1684             char value[PROPERTY_VALUE_MAX];
1685             property_get("persist.camera.mem.usecache", value, "1");
1686             if (atoi(value) == 0) {
1687                 bCachedMem = QCAMERA_ION_USE_NOCACHE;
1688             }
1689             CDBG_HIGH("%s: vidoe buf using cached memory = %d", __func__, bCachedMem);
1690             mem = new QCameraVideoMemory(mGetMemory, bCachedMem);
1691         }
1692         break;
1693     case CAM_STREAM_TYPE_DEFAULT:
1694     case CAM_STREAM_TYPE_MAX:
1695     default:
1696         break;
1697     }
1698     if (!mem) {
1699         return NULL;
1700     }
1701 
1702     if (bufferCnt > 0) {
1703         if (mParameters.isSecureMode() &&
1704             (stream_type == CAM_STREAM_TYPE_RAW) &&
1705             (mParameters.isRdiMode())) {
1706             ALOGD("%s: Allocating %d secure buffers of size %d ", __func__, bufferCnt, size);
1707             rc = mem->allocate(bufferCnt, size, SECURE);
1708         } else {
1709             rc = mem->allocate(bufferCnt, size, NON_SECURE);
1710         }
1711         if (rc < 0) {
1712             delete mem;
1713             return NULL;
1714         }
1715         bufferCnt = mem->getCnt();
1716     }
1717     return mem;
1718 }
1719 
1720 /*===========================================================================
1721  * FUNCTION   : allocateMoreStreamBuf
1722  *
1723  * DESCRIPTION: alocate more stream buffers from the memory object
1724  *
1725  * PARAMETERS :
1726  *   @mem_obj      : memory object ptr
1727  *   @size         : size of buffer
1728  *   @bufferCnt    : [IN/OUT] additional number of buffers to be allocated.
1729  *                   output will be the number of total buffers
1730  *
1731  * RETURN     : int32_t type of status
1732  *              NO_ERROR  -- success
1733  *              none-zero failure code
1734  *==========================================================================*/
allocateMoreStreamBuf(QCameraMemory * mem_obj,int size,uint8_t & bufferCnt)1735 int32_t QCamera2HardwareInterface::allocateMoreStreamBuf(QCameraMemory *mem_obj,
1736                                                          int size,
1737                                                          uint8_t &bufferCnt)
1738 {
1739     int rc = NO_ERROR;
1740 
1741     if (bufferCnt > 0) {
1742         rc = mem_obj->allocateMore(bufferCnt, size);
1743         bufferCnt = mem_obj->getCnt();
1744     }
1745     return rc;
1746 }
1747 
1748 /*===========================================================================
1749  * FUNCTION   : allocateStreamInfoBuf
1750  *
1751  * DESCRIPTION: alocate stream info buffer
1752  *
1753  * PARAMETERS :
1754  *   @stream_type  : type of stream
1755  *
1756  * RETURN     : ptr to a memory obj that holds stream info buffer.
1757  *              NULL if failed
1758  *==========================================================================*/
allocateStreamInfoBuf(cam_stream_type_t stream_type)1759 QCameraHeapMemory *QCamera2HardwareInterface::allocateStreamInfoBuf(
1760     cam_stream_type_t stream_type)
1761 {
1762     int rc = NO_ERROR;
1763     const char *effect;
1764     char value[PROPERTY_VALUE_MAX];
1765     bool raw_yuv = false;
1766 
1767     QCameraHeapMemory *streamInfoBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
1768     if (!streamInfoBuf) {
1769         ALOGE("allocateStreamInfoBuf: Unable to allocate streamInfo object");
1770         return NULL;
1771     }
1772 
1773     rc = streamInfoBuf->allocate(1, sizeof(cam_stream_info_t), NON_SECURE);
1774     if (rc < 0) {
1775         ALOGE("allocateStreamInfoBuf: Failed to allocate stream info memory");
1776         delete streamInfoBuf;
1777         return NULL;
1778     }
1779 
1780     cam_stream_info_t *streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(0);
1781     memset(streamInfo, 0, sizeof(cam_stream_info_t));
1782     streamInfo->stream_type = stream_type;
1783     rc = mParameters.getStreamFormat(stream_type, streamInfo->fmt);
1784     rc = mParameters.getStreamDimension(stream_type, streamInfo->dim);
1785     rc = mParameters.getStreamRotation(stream_type, streamInfo->pp_config, streamInfo->dim);
1786     streamInfo->num_bufs = getBufNumRequired(stream_type);
1787     streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
1788     streamInfo->is_secure = NON_SECURE;
1789     switch (stream_type) {
1790     case CAM_STREAM_TYPE_SNAPSHOT:
1791         if ((mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) ||
1792             mLongshotEnabled) {
1793             streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
1794         } else {
1795             streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
1796             streamInfo->num_of_burst = mParameters.getNumOfSnapshots()
1797                 + mParameters.getNumOfExtraHDRInBufsIfNeeded()
1798                 - mParameters.getNumOfExtraHDROutBufsIfNeeded()
1799                 + mParameters.getNumOfExtraBuffersForImageProc();
1800         }
1801         break;
1802     case CAM_STREAM_TYPE_RAW:
1803         property_get("persist.camera.raw_yuv", value, "0");
1804         raw_yuv = atoi(value) > 0 ? true : false;
1805 
1806         if (mParameters.isZSLMode() || isRdiMode() || raw_yuv) {
1807             CDBG_HIGH("RDI_DEBUG %s[%d]: CAM_STREAM_TYPE_RAW",
1808               __func__, __LINE__);
1809             streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
1810         } else {
1811             streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
1812             streamInfo->num_of_burst = mParameters.getNumOfSnapshots();
1813         }
1814         if (mParameters.isSecureMode() && mParameters.isRdiMode()) {
1815             streamInfo->is_secure = SECURE;
1816         } else {
1817             streamInfo->is_secure = NON_SECURE;
1818         }
1819         break;
1820     case CAM_STREAM_TYPE_POSTVIEW:
1821         if (mLongshotEnabled) {
1822             streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
1823         } else {
1824             streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
1825             streamInfo->num_of_burst = mParameters.getNumOfSnapshots()
1826                 + mParameters.getNumOfExtraHDRInBufsIfNeeded()
1827                 - mParameters.getNumOfExtraHDROutBufsIfNeeded()
1828                 + mParameters.getNumOfExtraBuffersForImageProc();
1829         }
1830         break;
1831     case CAM_STREAM_TYPE_VIDEO:
1832         streamInfo->useAVTimer = mParameters.isAVTimerEnabled();
1833         streamInfo->dis_enable = mParameters.isDISEnabled();
1834     case CAM_STREAM_TYPE_PREVIEW:
1835         if (mParameters.getRecordingHintValue()) {
1836             const char* dis_param = mParameters.get(QCameraParameters::KEY_QC_DIS);
1837             bool disEnabled = (dis_param != NULL)
1838                     && !strcmp(dis_param,QCameraParameters::VALUE_ENABLE);
1839             if(disEnabled) {
1840                 char value[PROPERTY_VALUE_MAX];
1841                 property_get("persist.camera.is_type", value, "0");
1842                 streamInfo->is_type = static_cast<cam_is_type_t>(atoi(value));
1843             } else {
1844                 streamInfo->is_type = IS_TYPE_NONE;
1845             }
1846         }
1847         if (mParameters.isSecureMode()) {
1848             streamInfo->is_secure = SECURE;
1849         }
1850         break;
1851     default:
1852         break;
1853     }
1854 
1855     ALOGD("%s: Stream type %d is secure: %d", __func__, stream_type, streamInfo->is_secure);
1856     if ((!isZSLMode() ||
1857         (isZSLMode() && (stream_type != CAM_STREAM_TYPE_SNAPSHOT))) &&
1858         !mParameters.isHDREnabled()) {
1859         //set flip mode based on Stream type;
1860         int flipMode = mParameters.getFlipMode(stream_type);
1861         if (flipMode > 0) {
1862             streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_FLIP;
1863             streamInfo->pp_config.flip = flipMode;
1864         }
1865     }
1866 
1867     if (!isZSLMode()) {
1868         if ((gCamCaps[mCameraId]->min_required_pp_mask & CAM_QCOM_FEATURE_SHARPNESS) &&
1869                 !mParameters.isOptiZoomEnabled()) {
1870             streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_SHARPNESS;
1871             streamInfo->pp_config.sharpness = mParameters.getInt(QCameraParameters::KEY_QC_SHARPNESS);
1872         }
1873 
1874         if (gCamCaps[mCameraId]->min_required_pp_mask & CAM_QCOM_FEATURE_EFFECT) {
1875             streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_EFFECT;
1876             effect = mParameters.get(CameraParameters::KEY_EFFECT);
1877             streamInfo->pp_config.effect = getEffectValue(effect);
1878         }
1879         if (mParameters.isWNREnabled() && (mParameters.getRecordingHintValue() == false)) {
1880             streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_DENOISE2D;
1881             streamInfo->pp_config.denoise2d.denoise_enable = 1;
1882             streamInfo->pp_config.denoise2d.process_plates = mParameters.getWaveletDenoiseProcessPlate();
1883         }
1884     }
1885     return streamInfoBuf;
1886 }
1887 
1888 /*===========================================================================
1889  * FUNCTION   : setPreviewWindow
1890  *
1891  * DESCRIPTION: set preview window impl
1892  *
1893  * PARAMETERS :
1894  *   @window  : ptr to window ops table struct
1895  *
1896  * RETURN     : int32_t type of status
1897  *              NO_ERROR  -- success
1898  *              none-zero failure code
1899  *==========================================================================*/
setPreviewWindow(struct preview_stream_ops * window)1900 int QCamera2HardwareInterface::setPreviewWindow(
1901         struct preview_stream_ops *window)
1902 {
1903     mPreviewWindow = window;
1904     return NO_ERROR;
1905 }
1906 
1907 /*===========================================================================
1908  * FUNCTION   : setCallBacks
1909  *
1910  * DESCRIPTION: set callbacks impl
1911  *
1912  * PARAMETERS :
1913  *   @notify_cb  : notify cb
1914  *   @data_cb    : data cb
1915  *   @data_cb_timestamp : data cb with time stamp
1916  *   @get_memory : request memory ops table
1917  *   @user       : user data ptr
1918  *
1919  * RETURN     : int32_t type of status
1920  *              NO_ERROR  -- success
1921  *              none-zero failure code
1922  *==========================================================================*/
setCallBacks(camera_notify_callback notify_cb,camera_data_callback data_cb,camera_data_timestamp_callback data_cb_timestamp,camera_request_memory get_memory,void * user)1923 int QCamera2HardwareInterface::setCallBacks(camera_notify_callback notify_cb,
1924                                             camera_data_callback data_cb,
1925                                             camera_data_timestamp_callback data_cb_timestamp,
1926                                             camera_request_memory get_memory,
1927                                             void *user)
1928 {
1929     mNotifyCb        = notify_cb;
1930     mDataCb          = data_cb;
1931     mDataCbTimestamp = data_cb_timestamp;
1932     mGetMemory       = get_memory;
1933     mCallbackCookie  = user;
1934     m_cbNotifier.setCallbacks(notify_cb, data_cb, data_cb_timestamp, user);
1935     return NO_ERROR;
1936 }
1937 
1938 /*===========================================================================
1939  * FUNCTION   : enableMsgType
1940  *
1941  * DESCRIPTION: enable msg type impl
1942  *
1943  * PARAMETERS :
1944  *   @msg_type  : msg type mask to be enabled
1945  *
1946  * RETURN     : int32_t type of status
1947  *              NO_ERROR  -- success
1948  *              none-zero failure code
1949  *==========================================================================*/
enableMsgType(int32_t msg_type)1950 int QCamera2HardwareInterface::enableMsgType(int32_t msg_type)
1951 {
1952     mMsgEnabled |= msg_type;
1953     return NO_ERROR;
1954 }
1955 
1956 /*===========================================================================
1957  * FUNCTION   : disableMsgType
1958  *
1959  * DESCRIPTION: disable msg type impl
1960  *
1961  * PARAMETERS :
1962  *   @msg_type  : msg type mask to be disabled
1963  *
1964  * RETURN     : int32_t type of status
1965  *              NO_ERROR  -- success
1966  *              none-zero failure code
1967  *==========================================================================*/
disableMsgType(int32_t msg_type)1968 int QCamera2HardwareInterface::disableMsgType(int32_t msg_type)
1969 {
1970     mMsgEnabled &= ~msg_type;
1971     return NO_ERROR;
1972 }
1973 
1974 /*===========================================================================
1975  * FUNCTION   : msgTypeEnabled
1976  *
1977  * DESCRIPTION: impl to determine if certain msg_type is enabled
1978  *
1979  * PARAMETERS :
1980  *   @msg_type  : msg type mask
1981  *
1982  * RETURN     : 0 -- not enabled
1983  *              none 0 -- enabled
1984  *==========================================================================*/
msgTypeEnabled(int32_t msg_type)1985 int QCamera2HardwareInterface::msgTypeEnabled(int32_t msg_type)
1986 {
1987     return (mMsgEnabled & msg_type);
1988 }
1989 
1990 /*===========================================================================
1991  * FUNCTION   : msgTypeEnabledWithLock
1992  *
1993  * DESCRIPTION: impl to determine if certain msg_type is enabled with lock
1994  *
1995  * PARAMETERS :
1996  *   @msg_type  : msg type mask
1997  *
1998  * RETURN     : 0 -- not enabled
1999  *              none 0 -- enabled
2000  *==========================================================================*/
msgTypeEnabledWithLock(int32_t msg_type)2001 int QCamera2HardwareInterface::msgTypeEnabledWithLock(int32_t msg_type)
2002 {
2003     int enabled = 0;
2004     lockAPI();
2005     enabled = mMsgEnabled & msg_type;
2006     unlockAPI();
2007     return enabled;
2008 }
2009 
2010 /*===========================================================================
2011  * FUNCTION   : startPreview
2012  *
2013  * DESCRIPTION: start preview impl
2014  *
2015  * PARAMETERS : none
2016  *
2017  * RETURN     : int32_t type of status
2018  *              NO_ERROR  -- success
2019  *              none-zero failure code
2020  *==========================================================================*/
startPreview()2021 int QCamera2HardwareInterface::startPreview()
2022 {
2023     int32_t rc = NO_ERROR;
2024     CDBG_HIGH("%s: E", __func__);
2025     // start preview stream
2026     if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() !=true) {
2027         rc = startChannel(QCAMERA_CH_TYPE_ZSL);
2028     } else {
2029         rc = startChannel(QCAMERA_CH_TYPE_PREVIEW);
2030     }
2031     CDBG_HIGH("%s: X", __func__);
2032     return rc;
2033 }
2034 
2035 /*===========================================================================
2036  * FUNCTION   : stopPreview
2037  *
2038  * DESCRIPTION: stop preview impl
2039  *
2040  * PARAMETERS : none
2041  *
2042  * RETURN     : int32_t type of status
2043  *              NO_ERROR  -- success
2044  *              none-zero failure code
2045  *==========================================================================*/
stopPreview()2046 int QCamera2HardwareInterface::stopPreview()
2047 {
2048     CDBG_HIGH("%s: E", __func__);
2049     // stop preview stream
2050     stopChannel(QCAMERA_CH_TYPE_ZSL);
2051     stopChannel(QCAMERA_CH_TYPE_PREVIEW);
2052 
2053     // delete all channels from preparePreview
2054     unpreparePreview();
2055 
2056     //reset focus state
2057     m_currentFocusState = CAM_AF_NOT_FOCUSED;
2058     CDBG_HIGH("%s: X", __func__);
2059     return NO_ERROR;
2060 }
2061 
2062 /*===========================================================================
2063  * FUNCTION   : storeMetaDataInBuffers
2064  *
2065  * DESCRIPTION: enable store meta data in buffers for video frames impl
2066  *
2067  * PARAMETERS :
2068  *   @enable  : flag if need enable
2069  *
2070  * RETURN     : int32_t type of status
2071  *              NO_ERROR  -- success
2072  *              none-zero failure code
2073  *==========================================================================*/
storeMetaDataInBuffers(int enable)2074 int QCamera2HardwareInterface::storeMetaDataInBuffers(int enable)
2075 {
2076     mStoreMetaDataInFrame = enable;
2077     return NO_ERROR;
2078 }
2079 
2080 /*===========================================================================
2081  * FUNCTION   : startRecording
2082  *
2083  * DESCRIPTION: start recording impl
2084  *
2085  * PARAMETERS : none
2086  *
2087  * RETURN     : int32_t type of status
2088  *              NO_ERROR  -- success
2089  *              none-zero failure code
2090  *==========================================================================*/
startRecording()2091 int QCamera2HardwareInterface::startRecording()
2092 {
2093     int32_t rc = NO_ERROR;
2094     CDBG_HIGH("%s: E", __func__);
2095     if (mParameters.getRecordingHintValue() == false) {
2096         ALOGE("%s: start recording when hint is false, stop preview first", __func__);
2097         stopPreview();
2098 
2099         // Set recording hint to TRUE
2100         mParameters.updateRecordingHintValue(TRUE);
2101         rc = preparePreview();
2102         if (rc == NO_ERROR) {
2103             rc = startChannel(QCAMERA_CH_TYPE_PREVIEW);
2104         }
2105     }
2106 
2107     if (rc == NO_ERROR) {
2108         rc = startChannel(QCAMERA_CH_TYPE_VIDEO);
2109     }
2110 
2111 #ifdef HAS_MULTIMEDIA_HINTS
2112     if (rc == NO_ERROR) {
2113         if (m_pPowerModule) {
2114             if (m_pPowerModule->powerHint) {
2115                 m_pPowerModule->powerHint(m_pPowerModule, POWER_HINT_VIDEO_ENCODE, (void *)"state=1");
2116             }
2117         }
2118     }
2119 #endif
2120     CDBG_HIGH("%s: X", __func__);
2121     return rc;
2122 }
2123 
2124 /*===========================================================================
2125  * FUNCTION   : stopRecording
2126  *
2127  * DESCRIPTION: stop recording impl
2128  *
2129  * PARAMETERS : none
2130  *
2131  * RETURN     : int32_t type of status
2132  *              NO_ERROR  -- success
2133  *              none-zero failure code
2134  *==========================================================================*/
stopRecording()2135 int QCamera2HardwareInterface::stopRecording()
2136 {
2137     int rc = stopChannel(QCAMERA_CH_TYPE_VIDEO);
2138     CDBG_HIGH("%s: E", __func__);
2139 #ifdef HAS_MULTIMEDIA_HINTS
2140     if (m_pPowerModule) {
2141         if (m_pPowerModule->powerHint) {
2142             m_pPowerModule->powerHint(m_pPowerModule, POWER_HINT_VIDEO_ENCODE, (void *)"state=0");
2143         }
2144     }
2145 #endif
2146     CDBG_HIGH("%s: X", __func__);
2147     return rc;
2148 }
2149 
2150 /*===========================================================================
2151  * FUNCTION   : releaseRecordingFrame
2152  *
2153  * DESCRIPTION: return video frame impl
2154  *
2155  * PARAMETERS :
2156  *   @opaque  : ptr to video frame to be returned
2157  *
2158  * RETURN     : int32_t type of status
2159  *              NO_ERROR  -- success
2160  *              none-zero failure code
2161  *==========================================================================*/
releaseRecordingFrame(const void * opaque)2162 int QCamera2HardwareInterface::releaseRecordingFrame(const void * opaque)
2163 {
2164     int32_t rc = UNKNOWN_ERROR;
2165     QCameraVideoChannel *pChannel =
2166         (QCameraVideoChannel *)m_channels[QCAMERA_CH_TYPE_VIDEO];
2167     CDBG_HIGH("%s: opaque data = %p", __func__,opaque);
2168     if(pChannel != NULL) {
2169         rc = pChannel->releaseFrame(opaque, mStoreMetaDataInFrame > 0);
2170     }
2171     return rc;
2172 }
2173 
2174 /*===========================================================================
2175  * FUNCTION   : autoFocus
2176  *
2177  * DESCRIPTION: start auto focus impl
2178  *
2179  * PARAMETERS : none
2180  *
2181  * RETURN     : int32_t type of status
2182  *              NO_ERROR  -- success
2183  *              none-zero failure code
2184  *==========================================================================*/
autoFocus()2185 int QCamera2HardwareInterface::autoFocus()
2186 {
2187     int rc = NO_ERROR;
2188     cam_focus_mode_type focusMode = mParameters.getFocusMode();
2189 
2190     switch (focusMode) {
2191     case CAM_FOCUS_MODE_AUTO:
2192     case CAM_FOCUS_MODE_MACRO:
2193     case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
2194     case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
2195         rc = mCameraHandle->ops->do_auto_focus(mCameraHandle->camera_handle);
2196         break;
2197     case CAM_FOCUS_MODE_INFINITY:
2198     case CAM_FOCUS_MODE_FIXED:
2199     case CAM_FOCUS_MODE_EDOF:
2200     default:
2201         ALOGE("%s: No ops in focusMode (%d)", __func__, focusMode);
2202         rc = sendEvtNotify(CAMERA_MSG_FOCUS, true, 0);
2203         break;
2204     }
2205     return rc;
2206 }
2207 
2208 /*===========================================================================
2209  * FUNCTION   : cancelAutoFocus
2210  *
2211  * DESCRIPTION: cancel auto focus impl
2212  *
2213  * PARAMETERS : none
2214  *
2215  * RETURN     : int32_t type of status
2216  *              NO_ERROR  -- success
2217  *              none-zero failure code
2218  *==========================================================================*/
cancelAutoFocus()2219 int QCamera2HardwareInterface::cancelAutoFocus()
2220 {
2221     int rc = NO_ERROR;
2222     cam_focus_mode_type focusMode = mParameters.getFocusMode();
2223 
2224     switch (focusMode) {
2225     case CAM_FOCUS_MODE_AUTO:
2226     case CAM_FOCUS_MODE_MACRO:
2227     case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
2228     case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
2229         rc = mCameraHandle->ops->cancel_auto_focus(mCameraHandle->camera_handle);
2230         m_currentFocusState = CAM_AF_CANCELLED;
2231         break;
2232     case CAM_FOCUS_MODE_INFINITY:
2233     case CAM_FOCUS_MODE_FIXED:
2234     case CAM_FOCUS_MODE_EDOF:
2235     default:
2236         CDBG("%s: No ops in focusMode (%d)", __func__, focusMode);
2237         break;
2238     }
2239     return rc;
2240 }
2241 
2242 /*===========================================================================
2243  * FUNCTION   : processUFDumps
2244  *
2245  * DESCRIPTION: process UF jpeg dumps for refocus support
2246  *
2247  * PARAMETERS :
2248  *   @evt     : payload of jpeg event, including information about jpeg encoding
2249  *              status, jpeg size and so on.
2250  *
2251  * RETURN     : int32_t type of status
2252  *              NO_ERROR  -- success
2253  *              none-zero failure code
2254  *
2255  * NOTE       : none
2256  *==========================================================================*/
processUFDumps(qcamera_jpeg_evt_payload_t * evt)2257 bool QCamera2HardwareInterface::processUFDumps(qcamera_jpeg_evt_payload_t *evt)
2258 {
2259    bool ret = true;
2260    if (mParameters.isUbiRefocus()) {
2261        int index = getOutputImageCount();
2262        bool allFocusImage = (index == ((int)mParameters.UfOutputCount()-1));
2263        char name[CAM_FN_CNT];
2264 
2265        camera_memory_t *jpeg_mem = NULL;
2266        omx_jpeg_ouput_buf_t *jpeg_out = NULL;
2267        uint32_t dataLen;
2268        uint8_t *dataPtr;
2269        if (!m_postprocessor.getJpegMemOpt()) {
2270            dataLen = evt->out_data.buf_filled_len;
2271            dataPtr = evt->out_data.buf_vaddr;
2272        } else {
2273            jpeg_out  = (omx_jpeg_ouput_buf_t*) evt->out_data.buf_vaddr;
2274            if (!jpeg_out) {
2275               ALOGE("%s:%d] Null pointer detected",  __func__, __LINE__);
2276               return false;
2277            }
2278            jpeg_mem = (camera_memory_t *)jpeg_out->mem_hdl;
2279            if (!jpeg_mem) {
2280               ALOGE("%s:%d] Null pointer detected",  __func__, __LINE__);
2281               return false;
2282            }
2283            dataPtr = (uint8_t *)jpeg_mem->data;
2284            dataLen = jpeg_mem->size;
2285        }
2286 
2287        if (allFocusImage)  {
2288            strncpy(name, "AllFocusImage", CAM_FN_CNT - 1);
2289            index = -1;
2290        } else {
2291            strncpy(name, "0", CAM_FN_CNT - 1);
2292        }
2293        CAM_DUMP_TO_FILE("/data/local/ubifocus", name, index, "jpg",
2294            dataPtr, dataLen);
2295        CDBG("%s:%d] Dump the image %d %d allFocusImage %d", __func__, __LINE__,
2296            getOutputImageCount(), index, allFocusImage);
2297        setOutputImageCount(getOutputImageCount() + 1);
2298        if (!allFocusImage) {
2299            ret = false;
2300        }
2301    }
2302    return ret;
2303 }
2304 
2305 /*===========================================================================
2306  * FUNCTION   : configureAdvancedCapture
2307  *
2308  * DESCRIPTION: configure Advanced Capture.
2309  *
2310  * PARAMETERS : none
2311  *
2312  * RETURN     : int32_t type of status
2313  *              NO_ERROR  -- success
2314  *              none-zero failure code
2315  *==========================================================================*/
configureAdvancedCapture()2316 int32_t QCamera2HardwareInterface::configureAdvancedCapture()
2317 {
2318     CDBG_HIGH("%s: E",__func__);
2319     int32_t rc = NO_ERROR;
2320 
2321     setOutputImageCount(0);
2322     mParameters.setDisplayFrame(FALSE);
2323     if (mParameters.isUbiFocusEnabled()) {
2324         rc = configureAFBracketing();
2325     } else if (mParameters.isOptiZoomEnabled()) {
2326         rc = configureOptiZoom();
2327     } else if (mParameters.isChromaFlashEnabled()) {
2328         rc = configureFlashBracketing();
2329     } else if (mParameters.isHDREnabled()) {
2330         rc = configureHDRBracketing();
2331     } else if (mParameters.isAEBracketEnabled()) {
2332         rc = configureAEBracketing();
2333     } else {
2334         ALOGE("%s: No Advanced Capture feature enabled!! ", __func__);
2335         rc = BAD_VALUE;
2336     }
2337     CDBG_HIGH("%s: X",__func__);
2338     return rc;
2339 }
2340 
2341 /*===========================================================================
2342  * FUNCTION   : configureAFBracketing
2343  *
2344  * DESCRIPTION: configure AF Bracketing.
2345  *
2346  * PARAMETERS : none
2347  *
2348  * RETURN     : int32_t type of status
2349  *              NO_ERROR  -- success
2350  *              none-zero failure code
2351  *==========================================================================*/
configureAFBracketing(bool enable)2352 int32_t QCamera2HardwareInterface::configureAFBracketing(bool enable)
2353 {
2354     CDBG_HIGH("%s: E",__func__);
2355     int32_t rc = NO_ERROR;
2356     cam_af_bracketing_t *af_bracketing_need;
2357     af_bracketing_need =
2358         &gCamCaps[mCameraId]->ubifocus_af_bracketing_need;
2359 
2360     //Enable AF Bracketing.
2361     cam_af_bracketing_t afBracket;
2362     memset(&afBracket, 0, sizeof(cam_af_bracketing_t));
2363     afBracket.enable = enable;
2364     afBracket.burst_count = af_bracketing_need->burst_count;
2365 
2366     for(int8_t i = 0; i < MAX_AF_BRACKETING_VALUES; i++) {
2367         afBracket.focus_steps[i] = af_bracketing_need->focus_steps[i];
2368         CDBG_HIGH("%s: focus_step[%d] = %d", __func__, i, afBracket.focus_steps[i]);
2369     }
2370     //Send cmd to backend to set AF Bracketing for Ubi Focus.
2371     rc = mParameters.commitAFBracket(afBracket);
2372     if ( NO_ERROR != rc ) {
2373         ALOGE("%s: cannot configure AF bracketing", __func__);
2374         return rc;
2375     }
2376     if (enable) {
2377         mParameters.set3ALock(QCameraParameters::VALUE_TRUE);
2378         mIs3ALocked = true;
2379     }
2380     CDBG_HIGH("%s: X",__func__);
2381     return rc;
2382 }
2383 
2384 /*===========================================================================
2385  * FUNCTION   : configureFlashBracketing
2386  *
2387  * DESCRIPTION: configure Flash Bracketing.
2388  *
2389  * PARAMETERS : none
2390  *
2391  * RETURN     : int32_t type of status
2392  *              NO_ERROR  -- success
2393  *              none-zero failure code
2394  *==========================================================================*/
configureFlashBracketing(bool enable)2395 int32_t QCamera2HardwareInterface::configureFlashBracketing(bool enable)
2396 {
2397     CDBG_HIGH("%s: E",__func__);
2398     int32_t rc = NO_ERROR;
2399 
2400     cam_flash_bracketing_t flashBracket;
2401     memset(&flashBracket, 0, sizeof(cam_flash_bracketing_t));
2402     flashBracket.enable = enable;
2403     //TODO: Hardcoded value.
2404     flashBracket.burst_count = 2;
2405     //Send cmd to backend to set Flash Bracketing for chroma flash.
2406     rc = mParameters.commitFlashBracket(flashBracket);
2407     if ( NO_ERROR != rc ) {
2408         ALOGE("%s: cannot configure AF bracketing", __func__);
2409     }
2410     CDBG_HIGH("%s: X",__func__);
2411     return rc;
2412 }
2413 
2414 /*===========================================================================
2415  * FUNCTION   : configureHDRBracketing
2416  *
2417  * DESCRIPTION: configure HDR Bracketing.
2418  *
2419  * PARAMETERS : none
2420  *
2421  * RETURN     : int32_t type of status
2422  *              NO_ERROR  -- success
2423  *              none-zero failure code
2424  *==========================================================================*/
configureHDRBracketing()2425 int32_t QCamera2HardwareInterface::configureHDRBracketing()
2426 {
2427     CDBG_HIGH("%s: E",__func__);
2428     int32_t rc = NO_ERROR;
2429 
2430     // 'values' should be in "idx1,idx2,idx3,..." format
2431     uint8_t hdrFrameCount = gCamCaps[mCameraId]->hdr_bracketing_setting.num_frames;
2432     ALOGE("%s : HDR values %d, %d frame count: %d",
2433           __func__,
2434           (int8_t) gCamCaps[mCameraId]->hdr_bracketing_setting.exp_val.values[0],
2435           (int8_t) gCamCaps[mCameraId]->hdr_bracketing_setting.exp_val.values[1],
2436           hdrFrameCount);
2437 
2438     // Enable AE Bracketing for HDR
2439     cam_exp_bracketing_t aeBracket;
2440     memset(&aeBracket, 0, sizeof(cam_exp_bracketing_t));
2441     aeBracket.mode =
2442         gCamCaps[mCameraId]->hdr_bracketing_setting.exp_val.mode;
2443     String8 tmp;
2444     for ( unsigned int i = 0; i < hdrFrameCount ; i++ ) {
2445         tmp.appendFormat("%d",
2446             (int8_t) gCamCaps[mCameraId]->hdr_bracketing_setting.exp_val.values[i]);
2447         tmp.append(",");
2448     }
2449     if (mParameters.isHDR1xFrameEnabled()
2450         && mParameters.isHDR1xExtraBufferNeeded()) {
2451             tmp.appendFormat("%d", 0);
2452             tmp.append(",");
2453     }
2454 
2455     if( !tmp.isEmpty() &&
2456         ( MAX_EXP_BRACKETING_LENGTH > tmp.length() ) ) {
2457         //Trim last comma
2458         memset(aeBracket.values, '\0', MAX_EXP_BRACKETING_LENGTH);
2459         memcpy(aeBracket.values, tmp.string(), tmp.length() - 1);
2460     }
2461 
2462     ALOGE("%s : HDR config values %s",
2463           __func__,
2464           aeBracket.values);
2465     rc = mParameters.setHDRAEBracket(aeBracket);
2466     if ( NO_ERROR != rc ) {
2467         ALOGE("%s: cannot configure HDR bracketing", __func__);
2468         return rc;
2469     }
2470     CDBG_HIGH("%s: X",__func__);
2471     return rc;
2472 }
2473 
2474 /*===========================================================================
2475  * FUNCTION   : configureAEBracketing
2476  *
2477  * DESCRIPTION: configure AE Bracketing.
2478  *
2479  * PARAMETERS : none
2480  *
2481  * RETURN     : int32_t type of status
2482  *              NO_ERROR  -- success
2483  *              none-zero failure code
2484  *==========================================================================*/
configureAEBracketing()2485 int32_t QCamera2HardwareInterface::configureAEBracketing()
2486 {
2487     CDBG_HIGH("%s: E",__func__);
2488     int32_t rc = NO_ERROR;
2489 
2490     rc = mParameters.setAEBracketing();
2491     if ( NO_ERROR != rc ) {
2492         ALOGE("%s: cannot configure AE bracketing", __func__);
2493         return rc;
2494     }
2495     CDBG_HIGH("%s: X",__func__);
2496     return rc;
2497 }
2498 
2499 /*===========================================================================
2500  * FUNCTION   : configureOptiZoom
2501  *
2502  * DESCRIPTION: configure Opti Zoom.
2503  *
2504  * PARAMETERS : none
2505  *
2506  * RETURN     : int32_t type of status
2507  *              NO_ERROR  -- success
2508  *              none-zero failure code
2509  *==========================================================================*/
configureOptiZoom()2510 int32_t QCamera2HardwareInterface::configureOptiZoom()
2511 {
2512     int32_t rc = NO_ERROR;
2513 
2514     //store current zoom level.
2515     mZoomLevel = (uint8_t) mParameters.getInt(CameraParameters::KEY_ZOOM);
2516 
2517     //set zoom level to 1x;
2518     mParameters.setAndCommitZoom(0);
2519 
2520     mParameters.set3ALock(QCameraParameters::VALUE_TRUE);
2521     mIs3ALocked = true;
2522 
2523     return rc;
2524 }
2525 
2526 /*===========================================================================
2527  * FUNCTION   : startAdvancedCapture
2528  *
2529  * DESCRIPTION: starts advanced capture based on capture type
2530  *
2531  * PARAMETERS :
2532  *   @pChannel : channel.
2533  *
2534  * RETURN     : int32_t type of status
2535  *              NO_ERROR  -- success
2536  *              none-zero failure code
2537  *==========================================================================*/
startAdvancedCapture(QCameraPicChannel * pChannel)2538 int32_t QCamera2HardwareInterface::startAdvancedCapture(
2539     QCameraPicChannel *pChannel)
2540 {
2541     CDBG_HIGH("%s: Start bracketig",__func__);
2542     int32_t rc = NO_ERROR;
2543 
2544     if(mParameters.isUbiFocusEnabled()) {
2545         rc = pChannel->startAdvancedCapture(MM_CAMERA_AF_BRACKETING);
2546     } else if (mParameters.isChromaFlashEnabled()) {
2547         rc = pChannel->startAdvancedCapture(MM_CAMERA_FLASH_BRACKETING);
2548     } else if (mParameters.isHDREnabled() || mParameters.isAEBracketEnabled()) {
2549         rc = pChannel->startAdvancedCapture(MM_CAMERA_AE_BRACKETING);
2550     } else if (mParameters.isOptiZoomEnabled()) {
2551         rc = pChannel->startAdvancedCapture(MM_CAMERA_ZOOM_1X);
2552     } else {
2553         ALOGE("%s: No Advanced Capture feature enabled!",__func__);
2554         rc = BAD_VALUE;
2555     }
2556     return rc;
2557 }
2558 
2559 /*===========================================================================
2560  * FUNCTION   : takePicture
2561  *
2562  * DESCRIPTION: take picture impl
2563  *
2564  * PARAMETERS : none
2565  *
2566  * RETURN     : int32_t type of status
2567  *              NO_ERROR  -- success
2568  *              none-zero failure code
2569  *==========================================================================*/
takePicture()2570 int QCamera2HardwareInterface::takePicture()
2571 {
2572     int rc = NO_ERROR;
2573 
2574     // Get total number for snapshots (retro + regular)
2575     uint8_t numSnapshots = mParameters.getNumOfSnapshots();
2576     // Get number of retro-active snapshots
2577     uint8_t numRetroSnapshots = mParameters.getNumOfRetroSnapshots();
2578     CDBG_HIGH("%s: E", __func__);
2579 
2580     // Check if retro-active snapshots are not enabled
2581     if (!isRetroPicture() || !mParameters.isZSLMode()) {
2582       numRetroSnapshots = 0;
2583       CDBG_HIGH("%s: [ZSL Retro] Reset retro snaphot count to zero", __func__);
2584     }
2585     if (mParameters.isUbiFocusEnabled() ||
2586             mParameters.isOptiZoomEnabled() ||
2587             mParameters.isHDREnabled() ||
2588             mParameters.isChromaFlashEnabled() ||
2589             mParameters.isAEBracketEnabled()) {
2590         rc = configureAdvancedCapture();
2591         if (rc == NO_ERROR) {
2592             numSnapshots = mParameters.getBurstCountForAdvancedCapture();
2593         }
2594     }
2595     CDBG_HIGH("%s: [ZSL Retro] numSnapshots = %d, numRetroSnapshots = %d",
2596           __func__, numSnapshots, numRetroSnapshots);
2597 
2598     getOrientation();
2599     if (mParameters.isZSLMode()) {
2600         QCameraPicChannel *pZSLChannel =
2601             (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
2602         if (NULL != pZSLChannel) {
2603             // start postprocessor
2604             rc = m_postprocessor.start(pZSLChannel);
2605             if (rc != NO_ERROR) {
2606                 ALOGE("%s: cannot start postprocessor", __func__);
2607                 return rc;
2608             }
2609             if (mParameters.isUbiFocusEnabled() ||
2610                     mParameters.isOptiZoomEnabled() ||
2611                     mParameters.isHDREnabled() ||
2612                     mParameters.isChromaFlashEnabled() ||
2613                     mParameters.isAEBracketEnabled()) {
2614                 rc = startAdvancedCapture(pZSLChannel);
2615                 if (rc != NO_ERROR) {
2616                     ALOGE("%s: cannot start zsl advanced capture", __func__);
2617                     return rc;
2618                 }
2619             }
2620             if ( mLongshotEnabled ) {
2621                 mCameraHandle->ops->start_zsl_snapshot(
2622                         mCameraHandle->camera_handle,
2623                         pZSLChannel->getMyHandle());
2624             }
2625             rc = pZSLChannel->takePicture(numSnapshots, numRetroSnapshots);
2626             if (rc != NO_ERROR) {
2627                 ALOGE("%s: cannot take ZSL picture, stop pproc", __func__);
2628                 m_postprocessor.stop();
2629                 return rc;
2630             }
2631         } else {
2632             ALOGE("%s: ZSL channel is NULL", __func__);
2633             return UNKNOWN_ERROR;
2634         }
2635     } else {
2636 
2637         // start snapshot
2638         if (mParameters.isJpegPictureFormat() ||
2639             mParameters.isNV16PictureFormat() ||
2640             mParameters.isNV21PictureFormat()) {
2641 
2642             if (!isLongshotEnabled()) {
2643 
2644                 rc = addCaptureChannel();
2645                 // normal capture case
2646                 // need to stop preview channel
2647                 stopChannel(QCAMERA_CH_TYPE_PREVIEW);
2648                 delChannel(QCAMERA_CH_TYPE_PREVIEW);
2649 
2650                 rc = declareSnapshotStreams();
2651                 if (NO_ERROR != rc) {
2652                     delChannel(QCAMERA_CH_TYPE_CAPTURE);
2653                     return rc;
2654                 }
2655 
2656                 waitDefferedWork(mSnapshotJob);
2657                 waitDefferedWork(mMetadataJob);
2658                 waitDefferedWork(mRawdataJob);
2659 
2660                 {
2661                     DefferWorkArgs args;
2662                     DefferAllocBuffArgs allocArgs;
2663 
2664                     memset(&args, 0, sizeof(DefferWorkArgs));
2665                     memset(&allocArgs, 0, sizeof(DefferAllocBuffArgs));
2666 
2667                     allocArgs.ch = m_channels[QCAMERA_CH_TYPE_CAPTURE];
2668                     allocArgs.type = CAM_STREAM_TYPE_POSTVIEW;
2669                     args.allocArgs = allocArgs;
2670 
2671                     mPostviewJob = queueDefferedWork(CMD_DEFF_ALLOCATE_BUFF,
2672                             args);
2673 
2674                     if ( mPostviewJob == -1)
2675                         rc = UNKNOWN_ERROR;
2676                 }
2677 
2678                 waitDefferedWork(mPostviewJob);
2679             } else {
2680                 // normal capture case
2681                 // need to stop preview channel
2682                 stopChannel(QCAMERA_CH_TYPE_PREVIEW);
2683                 delChannel(QCAMERA_CH_TYPE_PREVIEW);
2684 
2685                 rc = declareSnapshotStreams();
2686                 if (NO_ERROR != rc) {
2687                     return rc;
2688                 }
2689 
2690                 rc = addCaptureChannel();
2691             }
2692 
2693             if ((rc == NO_ERROR) &&
2694                 (NULL != m_channels[QCAMERA_CH_TYPE_CAPTURE])) {
2695 
2696                 // configure capture channel
2697                 rc = m_channels[QCAMERA_CH_TYPE_CAPTURE]->config();
2698                 if (rc != NO_ERROR) {
2699                     ALOGE("%s: cannot configure capture channel", __func__);
2700                     delChannel(QCAMERA_CH_TYPE_CAPTURE);
2701                     return rc;
2702                 }
2703 
2704                 DefferWorkArgs args;
2705                 memset(&args, 0, sizeof(DefferWorkArgs));
2706 
2707                 args.pprocArgs = m_channels[QCAMERA_CH_TYPE_CAPTURE];
2708                 mReprocJob = queueDefferedWork(CMD_DEFF_PPROC_START,
2709                         args);
2710 
2711                 // start catpure channel
2712                 rc =  m_channels[QCAMERA_CH_TYPE_CAPTURE]->start();
2713                 if (rc != NO_ERROR) {
2714                     ALOGE("%s: cannot start capture channel", __func__);
2715                     delChannel(QCAMERA_CH_TYPE_CAPTURE);
2716                     return rc;
2717                 }
2718 
2719                 QCameraPicChannel *pCapChannel =
2720                     (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_CAPTURE];
2721                 if (NULL != pCapChannel) {
2722                     if (mParameters.isUbiFocusEnabled()|
2723                         mParameters.isChromaFlashEnabled()) {
2724                         rc = startAdvancedCapture(pCapChannel);
2725                         if (rc != NO_ERROR) {
2726                             ALOGE("%s: cannot start advanced capture", __func__);
2727                             return rc;
2728                         }
2729                     }
2730                 }
2731                 if ( mLongshotEnabled ) {
2732                     rc = longShot();
2733                     if (NO_ERROR != rc) {
2734                         delChannel(QCAMERA_CH_TYPE_CAPTURE);
2735                         return rc;
2736                     }
2737                 }
2738             } else {
2739                 ALOGE("%s: cannot add capture channel", __func__);
2740                 return rc;
2741             }
2742         } else {
2743 
2744             stopChannel(QCAMERA_CH_TYPE_PREVIEW);
2745             delChannel(QCAMERA_CH_TYPE_PREVIEW);
2746 
2747             rc = addRawChannel();
2748             if (rc == NO_ERROR) {
2749                 // start postprocessor
2750                 rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]);
2751                 if (rc != NO_ERROR) {
2752                     ALOGE("%s: cannot start postprocessor", __func__);
2753                     delChannel(QCAMERA_CH_TYPE_RAW);
2754                     return rc;
2755                 }
2756 
2757                 rc = startChannel(QCAMERA_CH_TYPE_RAW);
2758                 if (rc != NO_ERROR) {
2759                     ALOGE("%s: cannot start raw channel", __func__);
2760                     m_postprocessor.stop();
2761                     delChannel(QCAMERA_CH_TYPE_RAW);
2762                     return rc;
2763                 }
2764             } else {
2765                 ALOGE("%s: cannot add raw channel", __func__);
2766                 return rc;
2767             }
2768         }
2769     }
2770     CDBG_HIGH("%s: X", __func__);
2771     return rc;
2772 }
2773 
2774 /*===========================================================================
2775  * FUNCTION   : declareSnapshotStreams
2776  *
2777  * DESCRIPTION: Configure backend with expected snapshot streams
2778  *
2779  * PARAMETERS : none
2780  *
2781  * RETURN     : int32_t type of status
2782  *              NO_ERROR  -- success
2783  *              none-zero failure code
2784  *==========================================================================*/
declareSnapshotStreams()2785 int32_t QCamera2HardwareInterface::declareSnapshotStreams()
2786 {
2787     int rc = NO_ERROR;
2788 
2789     // Update stream info configuration
2790     pthread_mutex_lock(&m_parm_lock);
2791     rc = mParameters.setStreamConfigure(true, mLongshotEnabled);
2792     if (rc != NO_ERROR) {
2793         ALOGE("%s: setStreamConfigure failed %d", __func__, rc);
2794         pthread_mutex_unlock(&m_parm_lock);
2795         return rc;
2796     }
2797     pthread_mutex_unlock(&m_parm_lock);
2798 
2799     return rc;
2800 }
2801 
2802 /*===========================================================================
2803  * FUNCTION   : longShot
2804  *
2805  * DESCRIPTION: Queue one more ZSL frame
2806  *              in the longshot pipe.
2807  *
2808  * PARAMETERS : none
2809  *
2810  * RETURN     : int32_t type of status
2811  *              NO_ERROR  -- success
2812  *              none-zero failure code
2813  *==========================================================================*/
longShot()2814 int32_t QCamera2HardwareInterface::longShot()
2815 {
2816     int32_t rc = NO_ERROR;
2817     uint8_t numSnapshots = mParameters.getNumOfSnapshots();
2818     QCameraPicChannel *pChannel = NULL;
2819 
2820     if (mParameters.isZSLMode()) {
2821         pChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
2822     } else {
2823         pChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_CAPTURE];
2824     }
2825 
2826     if (NULL != pChannel) {
2827         rc = pChannel->takePicture(numSnapshots, 0);
2828     } else {
2829         ALOGE(" %s : Capture channel not initialized!", __func__);
2830         rc = NO_INIT;
2831         goto end;
2832     }
2833 
2834 end:
2835     return rc;
2836 }
2837 
2838 /*===========================================================================
2839  * FUNCTION   : stopCaptureChannel
2840  *
2841  * DESCRIPTION: Stops capture channel
2842  *
2843  * PARAMETERS :
2844  *   @destroy : Set to true to stop and delete camera channel.
2845  *              Set to false to only stop capture channel.
2846  *
2847  * RETURN     : int32_t type of status
2848  *              NO_ERROR  -- success
2849  *              none-zero failure code
2850  *==========================================================================*/
stopCaptureChannel(bool destroy)2851 int QCamera2HardwareInterface::stopCaptureChannel(bool destroy)
2852 {
2853     if (mParameters.isJpegPictureFormat() ||
2854         mParameters.isNV16PictureFormat() ||
2855         mParameters.isNV21PictureFormat()) {
2856         stopChannel(QCAMERA_CH_TYPE_CAPTURE);
2857         if (destroy) {
2858             // Destroy camera channel but dont release context
2859             delChannel(QCAMERA_CH_TYPE_CAPTURE, false);
2860         }
2861     }
2862 
2863     return NO_ERROR;
2864 }
2865 
2866 /*===========================================================================
2867  * FUNCTION   : cancelPicture
2868  *
2869  * DESCRIPTION: cancel picture impl
2870  *
2871  * PARAMETERS : none
2872  *
2873  * RETURN     : int32_t type of status
2874  *              NO_ERROR  -- success
2875  *              none-zero failure code
2876  *==========================================================================*/
cancelPicture()2877 int QCamera2HardwareInterface::cancelPicture()
2878 {
2879     waitDefferedWork(mReprocJob);
2880 
2881     //stop post processor
2882     m_postprocessor.stop();
2883 
2884     mParameters.setDisplayFrame(TRUE);
2885     if ( mParameters.isHDREnabled() || mParameters.isAEBracketEnabled()) {
2886         mParameters.stopAEBracket();
2887     }
2888 
2889     if (mParameters.isZSLMode()) {
2890         QCameraPicChannel *pZSLChannel =
2891             (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
2892         if (NULL != pZSLChannel) {
2893             pZSLChannel->cancelPicture();
2894         }
2895     } else {
2896 
2897         // normal capture case
2898         if (mParameters.isJpegPictureFormat() ||
2899             mParameters.isNV16PictureFormat() ||
2900             mParameters.isNV21PictureFormat()) {
2901             stopChannel(QCAMERA_CH_TYPE_CAPTURE);
2902             delChannel(QCAMERA_CH_TYPE_CAPTURE);
2903         } else {
2904             stopChannel(QCAMERA_CH_TYPE_RAW);
2905             delChannel(QCAMERA_CH_TYPE_RAW);
2906         }
2907     }
2908     if(mIs3ALocked) {
2909         mParameters.set3ALock(QCameraParameters::VALUE_FALSE);
2910         mIs3ALocked = false;
2911     }
2912     if (mParameters.isUbiFocusEnabled()) {
2913         configureAFBracketing(false);
2914     }
2915     if (mParameters.isChromaFlashEnabled()) {
2916       configureFlashBracketing(false);
2917     }
2918     if(mParameters.isOptiZoomEnabled()) {
2919         CDBG_HIGH("%s: Restoring previous zoom value!!",__func__);
2920         mParameters.setAndCommitZoom(mZoomLevel);
2921     }
2922     return NO_ERROR;
2923 }
2924 
2925 /*===========================================================================
2926  * FUNCTION   : Live_Snapshot_thread
2927  *
2928  * DESCRIPTION: Seperate thread for taking live snapshot during recording
2929  *
2930  * PARAMETERS : @data - pointer to QCamera2HardwareInterface class object
2931  *
2932  * RETURN     : none
2933  *==========================================================================*/
Live_Snapshot_thread(void * data)2934 void* Live_Snapshot_thread (void* data)
2935 {
2936 
2937     QCamera2HardwareInterface *hw = reinterpret_cast<QCamera2HardwareInterface *>(data);
2938     if (!hw) {
2939         ALOGE("take_picture_thread: NULL camera device");
2940         return (void *)BAD_VALUE;
2941     }
2942     hw->takeLiveSnapshot_internal();
2943     return (void* )NULL;
2944 }
2945 
2946 /*===========================================================================
2947  * FUNCTION   : takeLiveSnapshot
2948  *
2949  * DESCRIPTION: take live snapshot during recording
2950  *
2951  * PARAMETERS : none
2952  *
2953  * RETURN     : int32_t type of status
2954  *              NO_ERROR  -- success
2955  *              none-zero failure code
2956  *==========================================================================*/
takeLiveSnapshot()2957 int QCamera2HardwareInterface::takeLiveSnapshot()
2958 {
2959     int rc = NO_ERROR;
2960     rc= pthread_create(&mLiveSnapshotThread, NULL, Live_Snapshot_thread, (void *) this);
2961     return rc;
2962 }
2963 
2964 /*===========================================================================
2965  * FUNCTION   : takeLiveSnapshot_internal
2966  *
2967  * DESCRIPTION: take live snapshot during recording
2968  *
2969  * PARAMETERS : none
2970  *
2971  * RETURN     : int32_t type of status
2972  *              NO_ERROR  -- success
2973  *              none-zero failure code
2974  *==========================================================================*/
takeLiveSnapshot_internal()2975 int QCamera2HardwareInterface::takeLiveSnapshot_internal()
2976 {
2977     int rc;
2978 
2979     getOrientation();
2980 
2981     // start post processor
2982     rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_SNAPSHOT]);
2983 
2984     // start snapshot channel
2985     if (rc == NO_ERROR) {
2986         rc = startChannel(QCAMERA_CH_TYPE_SNAPSHOT);
2987     }
2988 
2989     if (rc != NO_ERROR) {
2990         rc = processAPI(QCAMERA_SM_EVT_CANCEL_PICTURE, NULL);
2991         rc = sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
2992     }
2993     return rc;
2994 }
2995 
2996 /*===========================================================================
2997  * FUNCTION   : cancelLiveSnapshot
2998  *
2999  * DESCRIPTION: cancel current live snapshot request
3000  *
3001  * PARAMETERS : none
3002  *
3003  * RETURN     : int32_t type of status
3004  *              NO_ERROR  -- success
3005  *              none-zero failure code
3006  *==========================================================================*/
cancelLiveSnapshot()3007 int QCamera2HardwareInterface::cancelLiveSnapshot()
3008 {
3009     int rc = NO_ERROR;
3010 
3011     if (mLiveSnapshotThread != 0) {
3012         pthread_join(mLiveSnapshotThread,NULL);
3013         mLiveSnapshotThread = 0;
3014     }
3015 
3016     //stop post processor
3017     m_postprocessor.stop();
3018 
3019     // stop snapshot channel
3020     rc = stopChannel(QCAMERA_CH_TYPE_SNAPSHOT);
3021 
3022     return rc;
3023 }
3024 
3025 /*===========================================================================
3026  * FUNCTION   : getParameters
3027  *
3028  * DESCRIPTION: get parameters impl
3029  *
3030  * PARAMETERS : none
3031  *
3032  * RETURN     : a string containing parameter pairs
3033  *==========================================================================*/
getParameters()3034 char* QCamera2HardwareInterface::getParameters()
3035 {
3036     char* strParams = NULL;
3037     String8 str;
3038 
3039     int cur_width, cur_height;
3040 
3041     //Need take care Scale picture size
3042     if(mParameters.m_reprocScaleParam.isScaleEnabled() &&
3043         mParameters.m_reprocScaleParam.isUnderScaling()){
3044         int scale_width, scale_height;
3045 
3046         mParameters.m_reprocScaleParam.getPicSizeFromAPK(scale_width,scale_height);
3047         mParameters.getPictureSize(&cur_width, &cur_height);
3048 
3049         String8 pic_size;
3050         char buffer[32];
3051         snprintf(buffer, sizeof(buffer), "%dx%d", scale_width, scale_height);
3052         pic_size.append(buffer);
3053         mParameters.set(CameraParameters::KEY_PICTURE_SIZE, pic_size);
3054     }
3055 
3056     str = mParameters.flatten( );
3057     strParams = (char *)malloc(sizeof(char)*(str.length()+1));
3058     if(strParams != NULL){
3059         memset(strParams, 0, sizeof(char)*(str.length()+1));
3060         strncpy(strParams, str.string(), str.length());
3061         strParams[str.length()] = 0;
3062     }
3063 
3064     if(mParameters.m_reprocScaleParam.isScaleEnabled() &&
3065         mParameters.m_reprocScaleParam.isUnderScaling()){
3066         //need set back picture size
3067         String8 pic_size;
3068         char buffer[32];
3069         snprintf(buffer, sizeof(buffer), "%dx%d", cur_width, cur_height);
3070         pic_size.append(buffer);
3071         mParameters.set(CameraParameters::KEY_PICTURE_SIZE, pic_size);
3072     }
3073     return strParams;
3074 }
3075 
3076 /*===========================================================================
3077  * FUNCTION   : putParameters
3078  *
3079  * DESCRIPTION: put parameters string impl
3080  *
3081  * PARAMETERS :
3082  *   @parms   : parameters string to be released
3083  *
3084  * RETURN     : int32_t type of status
3085  *              NO_ERROR  -- success
3086  *              none-zero failure code
3087  *==========================================================================*/
putParameters(char * parms)3088 int QCamera2HardwareInterface::putParameters(char *parms)
3089 {
3090     free(parms);
3091     return NO_ERROR;
3092 }
3093 
3094 /*===========================================================================
3095  * FUNCTION   : sendCommand
3096  *
3097  * DESCRIPTION: send command impl
3098  *
3099  * PARAMETERS :
3100  *   @command : command to be executed
3101  *   @arg1    : optional argument 1
3102  *   @arg2    : optional argument 2
3103  *
3104  * RETURN     : int32_t type of status
3105  *              NO_ERROR  -- success
3106  *              none-zero failure code
3107  *==========================================================================*/
sendCommand(int32_t command,int32_t,int32_t)3108 int QCamera2HardwareInterface::sendCommand(int32_t command, int32_t /*arg1*/, int32_t /*arg2*/)
3109 {
3110     int rc = NO_ERROR;
3111 
3112     switch (command) {
3113 #ifndef VANILLA_HAL
3114     case CAMERA_CMD_LONGSHOT_ON:
3115         // Longshot can only be enabled when image capture
3116         // is not active.
3117         if ( !m_stateMachine.isCaptureRunning() ) {
3118             mLongshotEnabled = true;
3119             mParameters.setLongshotEnable(mLongshotEnabled);
3120 
3121         } else {
3122             rc = NO_INIT;
3123         }
3124         break;
3125     case CAMERA_CMD_LONGSHOT_OFF:
3126         if ( mLongshotEnabled && m_stateMachine.isCaptureRunning() ) {
3127             cancelPicture();
3128             processEvt(QCAMERA_SM_EVT_SNAPSHOT_DONE, NULL);
3129             QCameraChannel *pZSLChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
3130             if (isZSLMode() && (NULL != pZSLChannel)) {
3131                 mCameraHandle->ops->stop_zsl_snapshot(
3132                         mCameraHandle->camera_handle,
3133                         pZSLChannel->getMyHandle());
3134             }
3135         }
3136         mLongshotEnabled = false;
3137         mParameters.setLongshotEnable(mLongshotEnabled);
3138         break;
3139     case CAMERA_CMD_HISTOGRAM_ON:
3140     case CAMERA_CMD_HISTOGRAM_OFF:
3141         rc = setHistogram(command == CAMERA_CMD_HISTOGRAM_ON? true : false);
3142         break;
3143 #endif
3144     case CAMERA_CMD_START_FACE_DETECTION:
3145     case CAMERA_CMD_STOP_FACE_DETECTION:
3146         mParameters.setFaceDetectionOption(command == CAMERA_CMD_START_FACE_DETECTION? true : false);
3147         rc = setFaceDetection(command == CAMERA_CMD_START_FACE_DETECTION? true : false);
3148         break;
3149 #ifndef VANILLA_HAL
3150     case CAMERA_CMD_HISTOGRAM_SEND_DATA:
3151 #endif
3152     default:
3153         rc = NO_ERROR;
3154         break;
3155     }
3156     return rc;
3157 }
3158 
3159 /*===========================================================================
3160  * FUNCTION   : registerFaceImage
3161  *
3162  * DESCRIPTION: register face image impl
3163  *
3164  * PARAMETERS :
3165  *   @img_ptr : ptr to image buffer
3166  *   @config  : ptr to config struct about input image info
3167  *   @faceID  : [OUT] face ID to uniquely identifiy the registered face image
3168  *
3169  * RETURN     : int32_t type of status
3170  *              NO_ERROR  -- success
3171  *              none-zero failure code
3172  *==========================================================================*/
registerFaceImage(void * img_ptr,cam_pp_offline_src_config_t * config,int32_t & faceID)3173 int QCamera2HardwareInterface::registerFaceImage(void *img_ptr,
3174                                                  cam_pp_offline_src_config_t *config,
3175                                                  int32_t &faceID)
3176 {
3177     int rc = NO_ERROR;
3178     faceID = -1;
3179 
3180     if (img_ptr == NULL || config == NULL) {
3181         ALOGE("%s: img_ptr or config is NULL", __func__);
3182         return BAD_VALUE;
3183     }
3184 
3185     // allocate ion memory for source image
3186     QCameraHeapMemory *imgBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
3187     if (imgBuf == NULL) {
3188         ALOGE("%s: Unable to new heap memory obj for image buf", __func__);
3189         return NO_MEMORY;
3190     }
3191 
3192     rc = imgBuf->allocate(1, config->input_buf_planes.plane_info.frame_len, NON_SECURE);
3193     if (rc < 0) {
3194         ALOGE("%s: Unable to allocate heap memory for image buf", __func__);
3195         delete imgBuf;
3196         return NO_MEMORY;
3197     }
3198 
3199     void *pBufPtr = imgBuf->getPtr(0);
3200     if (pBufPtr == NULL) {
3201         ALOGE("%s: image buf is NULL", __func__);
3202         imgBuf->deallocate();
3203         delete imgBuf;
3204         return NO_MEMORY;
3205     }
3206     memcpy(pBufPtr, img_ptr, config->input_buf_planes.plane_info.frame_len);
3207 
3208     cam_pp_feature_config_t pp_feature;
3209     memset(&pp_feature, 0, sizeof(cam_pp_feature_config_t));
3210     pp_feature.feature_mask = CAM_QCOM_FEATURE_REGISTER_FACE;
3211     QCameraReprocessChannel *pChannel =
3212         addOfflineReprocChannel(*config, pp_feature, NULL, NULL);
3213 
3214     if (pChannel == NULL) {
3215         ALOGE("%s: fail to add offline reprocess channel", __func__);
3216         imgBuf->deallocate();
3217         delete imgBuf;
3218         return UNKNOWN_ERROR;
3219     }
3220 
3221     rc = pChannel->start();
3222     if (rc != NO_ERROR) {
3223         ALOGE("%s: Cannot start reprocess channel", __func__);
3224         imgBuf->deallocate();
3225         delete imgBuf;
3226         delete pChannel;
3227         return rc;
3228     }
3229 
3230     rc = pChannel->doReprocess(imgBuf->getFd(0), imgBuf->getSize(0), faceID);
3231 
3232     // done with register face image, free imgbuf and delete reprocess channel
3233     imgBuf->deallocate();
3234     delete imgBuf;
3235     imgBuf = NULL;
3236     pChannel->stop();
3237     delete pChannel;
3238     pChannel = NULL;
3239 
3240     return rc;
3241 }
3242 
3243 /*===========================================================================
3244  * FUNCTION   : release
3245  *
3246  * DESCRIPTION: release camera resource impl
3247  *
3248  * PARAMETERS : none
3249  *
3250  * RETURN     : int32_t type of status
3251  *              NO_ERROR  -- success
3252  *              none-zero failure code
3253  *==========================================================================*/
release()3254 int QCamera2HardwareInterface::release()
3255 {
3256     // stop and delete all channels
3257     for (int i = 0; i <QCAMERA_CH_TYPE_MAX ; i++) {
3258         if (m_channels[i] != NULL) {
3259             stopChannel((qcamera_ch_type_enum_t)i);
3260             delChannel((qcamera_ch_type_enum_t)i);
3261         }
3262     }
3263 
3264     return NO_ERROR;
3265 }
3266 
3267 /*===========================================================================
3268  * FUNCTION   : dump
3269  *
3270  * DESCRIPTION: camera status dump impl
3271  *
3272  * PARAMETERS :
3273  *   @fd      : fd for the buffer to be dumped with camera status
3274  *
3275  * RETURN     : int32_t type of status
3276  *              NO_ERROR  -- success
3277  *              none-zero failure code
3278  *==========================================================================*/
dump(int fd)3279 int QCamera2HardwareInterface::dump(int fd)
3280 {
3281     dprintf(fd, "\n Camera HAL information Begin \n");
3282     dprintf(fd, "Camera ID: %d \n", mCameraId);
3283     dprintf(fd, "StoreMetaDataInFrame: %d \n", mStoreMetaDataInFrame);
3284     dprintf(fd, "\n Configuration: %s", mParameters.dump().string());
3285     dprintf(fd, "\n State Information: %s", m_stateMachine.dump().string());
3286     dprintf(fd, "\n Camera HAL information End \n");
3287     return NO_ERROR;
3288 }
3289 
3290 /*===========================================================================
3291  * FUNCTION   : processAPI
3292  *
3293  * DESCRIPTION: process API calls from upper layer
3294  *
3295  * PARAMETERS :
3296  *   @api         : API to be processed
3297  *   @api_payload : ptr to API payload if any
3298  *
3299  * RETURN     : int32_t type of status
3300  *              NO_ERROR  -- success
3301  *              none-zero failure code
3302  *==========================================================================*/
processAPI(qcamera_sm_evt_enum_t api,void * api_payload)3303 int QCamera2HardwareInterface::processAPI(qcamera_sm_evt_enum_t api, void *api_payload)
3304 {
3305     return m_stateMachine.procAPI(api, api_payload);
3306 }
3307 
3308 /*===========================================================================
3309  * FUNCTION   : processEvt
3310  *
3311  * DESCRIPTION: process Evt from backend via mm-camera-interface
3312  *
3313  * PARAMETERS :
3314  *   @evt         : event type to be processed
3315  *   @evt_payload : ptr to event payload if any
3316  *
3317  * RETURN     : int32_t type of status
3318  *              NO_ERROR  -- success
3319  *              none-zero failure code
3320  *==========================================================================*/
processEvt(qcamera_sm_evt_enum_t evt,void * evt_payload)3321 int QCamera2HardwareInterface::processEvt(qcamera_sm_evt_enum_t evt, void *evt_payload)
3322 {
3323     return m_stateMachine.procEvt(evt, evt_payload);
3324 }
3325 
3326 /*===========================================================================
3327  * FUNCTION   : processSyncEvt
3328  *
3329  * DESCRIPTION: process synchronous Evt from backend
3330  *
3331  * PARAMETERS :
3332  *   @evt         : event type to be processed
3333  *   @evt_payload : ptr to event payload if any
3334  *
3335  * RETURN     : int32_t type of status
3336  *              NO_ERROR  -- success
3337  *              none-zero failure code
3338  *==========================================================================*/
processSyncEvt(qcamera_sm_evt_enum_t evt,void * evt_payload)3339 int QCamera2HardwareInterface::processSyncEvt(qcamera_sm_evt_enum_t evt, void *evt_payload)
3340 {
3341     int rc = NO_ERROR;
3342 
3343     pthread_mutex_lock(&m_evtLock);
3344     rc =  processEvt(evt, evt_payload);
3345     if (rc == NO_ERROR) {
3346         memset(&m_evtResult, 0, sizeof(qcamera_api_result_t));
3347         while (m_evtResult.request_api != evt) {
3348             pthread_cond_wait(&m_evtCond, &m_evtLock);
3349         }
3350         rc =  m_evtResult.status;
3351     }
3352     pthread_mutex_unlock(&m_evtLock);
3353 
3354     return rc;
3355 }
3356 
3357 /*===========================================================================
3358  * FUNCTION   : evtHandle
3359  *
3360  * DESCRIPTION: Function registerd to mm-camera-interface to handle backend events
3361  *
3362  * PARAMETERS :
3363  *   @camera_handle : event type to be processed
3364  *   @evt           : ptr to event
3365  *   @user_data     : user data ptr
3366  *
3367  * RETURN     : none
3368  *==========================================================================*/
camEvtHandle(uint32_t,mm_camera_event_t * evt,void * user_data)3369 void QCamera2HardwareInterface::camEvtHandle(uint32_t /*camera_handle*/,
3370                                           mm_camera_event_t *evt,
3371                                           void *user_data)
3372 {
3373     QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)user_data;
3374     if (obj && evt) {
3375         mm_camera_event_t *payload =
3376             (mm_camera_event_t *)malloc(sizeof(mm_camera_event_t));
3377         if (NULL != payload) {
3378             *payload = *evt;
3379             obj->processEvt(QCAMERA_SM_EVT_EVT_NOTIFY, payload);
3380         }
3381     } else {
3382         ALOGE("%s: NULL user_data", __func__);
3383     }
3384 }
3385 
3386 /*===========================================================================
3387  * FUNCTION   : jpegEvtHandle
3388  *
3389  * DESCRIPTION: Function registerd to mm-jpeg-interface to handle jpeg events
3390  *
3391  * PARAMETERS :
3392  *   @status    : status of jpeg job
3393  *   @client_hdl: jpeg client handle
3394  *   @jobId     : jpeg job Id
3395  *   @p_ouput   : ptr to jpeg output result struct
3396  *   @userdata  : user data ptr
3397  *
3398  * RETURN     : none
3399  *==========================================================================*/
jpegEvtHandle(jpeg_job_status_t status,uint32_t,uint32_t jobId,mm_jpeg_output_t * p_output,void * userdata)3400 void QCamera2HardwareInterface::jpegEvtHandle(jpeg_job_status_t status,
3401                                               uint32_t /*client_hdl*/,
3402                                               uint32_t jobId,
3403                                               mm_jpeg_output_t *p_output,
3404                                               void *userdata)
3405 {
3406     QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)userdata;
3407     if (obj) {
3408         qcamera_jpeg_evt_payload_t *payload =
3409             (qcamera_jpeg_evt_payload_t *)malloc(sizeof(qcamera_jpeg_evt_payload_t));
3410         if (NULL != payload) {
3411             memset(payload, 0, sizeof(qcamera_jpeg_evt_payload_t));
3412             payload->status = status;
3413             payload->jobId = jobId;
3414             if (p_output != NULL) {
3415                 payload->out_data = *p_output;
3416             }
3417             obj->processUFDumps(payload);
3418             obj->processEvt(QCAMERA_SM_EVT_JPEG_EVT_NOTIFY, payload);
3419         }
3420     } else {
3421         ALOGE("%s: NULL user_data", __func__);
3422     }
3423 }
3424 
3425 /*===========================================================================
3426  * FUNCTION   : thermalEvtHandle
3427  *
3428  * DESCRIPTION: routine to handle thermal event notification
3429  *
3430  * PARAMETERS :
3431  *   @level      : thermal level
3432  *   @userdata   : userdata passed in during registration
3433  *   @data       : opaque data from thermal client
3434  *
3435  * RETURN     : int32_t type of status
3436  *              NO_ERROR  -- success
3437  *              none-zero failure code
3438  *==========================================================================*/
thermalEvtHandle(qcamera_thermal_level_enum_t level,void * userdata,void * data)3439 int QCamera2HardwareInterface::thermalEvtHandle(
3440         qcamera_thermal_level_enum_t level, void *userdata, void *data)
3441 {
3442     if (!mCameraOpened) {
3443         CDBG_HIGH("%s: Camera is not opened, no need to handle thermal evt", __func__);
3444         return NO_ERROR;
3445     }
3446 
3447     // Make sure thermal events are logged
3448     CDBG_HIGH("%s: level = %d, userdata = %p, data = %p",
3449         __func__, level, userdata, data);
3450     //We don't need to lockAPI, waitAPI here. QCAMERA_SM_EVT_THERMAL_NOTIFY
3451     // becomes an aync call. This also means we can only pass payload
3452     // by value, not by address.
3453     return processAPI(QCAMERA_SM_EVT_THERMAL_NOTIFY, (void *)level);
3454 }
3455 
3456 /*===========================================================================
3457  * FUNCTION   : sendEvtNotify
3458  *
3459  * DESCRIPTION: send event notify to notify thread
3460  *
3461  * PARAMETERS :
3462  *   @msg_type: msg type to be sent
3463  *   @ext1    : optional extension1
3464  *   @ext2    : optional extension2
3465  *
3466  * RETURN     : int32_t type of status
3467  *              NO_ERROR  -- success
3468  *              none-zero failure code
3469  *==========================================================================*/
sendEvtNotify(int32_t msg_type,int32_t ext1,int32_t ext2)3470 int32_t QCamera2HardwareInterface::sendEvtNotify(int32_t msg_type,
3471                                                  int32_t ext1,
3472                                                  int32_t ext2)
3473 {
3474     qcamera_callback_argm_t cbArg;
3475     memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
3476     cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK;
3477     cbArg.msg_type = msg_type;
3478     cbArg.ext1 = ext1;
3479     cbArg.ext2 = ext2;
3480     return m_cbNotifier.notifyCallback(cbArg);
3481 }
3482 
3483 /*===========================================================================
3484  * FUNCTION   : processAutoFocusEvent
3485  *
3486  * DESCRIPTION: process auto focus event
3487  *
3488  * PARAMETERS :
3489  *   @focus_data: struct containing auto focus result info
3490  *
3491  * RETURN     : int32_t type of status
3492  *              NO_ERROR  -- success
3493  *              none-zero failure code
3494  *==========================================================================*/
processAutoFocusEvent(cam_auto_focus_data_t & focus_data)3495 int32_t QCamera2HardwareInterface::processAutoFocusEvent(cam_auto_focus_data_t &focus_data)
3496 {
3497     int32_t ret = NO_ERROR;
3498     CDBG_HIGH("%s: E",__func__);
3499 
3500     cam_autofocus_state_t prevFocusState = m_currentFocusState;
3501     m_currentFocusState = focus_data.focus_state;
3502 
3503     cam_focus_mode_type focusMode = mParameters.getFocusMode();
3504     switch (focusMode) {
3505     case CAM_FOCUS_MODE_AUTO:
3506     case CAM_FOCUS_MODE_MACRO:
3507         if (focus_data.focus_state == CAM_AF_SCANNING) {
3508             // in the middle of focusing, just ignore it
3509             break;
3510         }
3511 
3512         // update focus distance
3513         mParameters.updateFocusDistances(&focus_data.focus_dist);
3514         ret = sendEvtNotify(CAMERA_MSG_FOCUS,
3515                             (focus_data.focus_state == CAM_AF_FOCUSED)? true : false,
3516                             0);
3517         if (CAM_AF_CANCELLED == prevFocusState) {
3518             //Notify CancelAF API
3519             qcamera_api_result_t result;
3520             memset(&result, 0, sizeof(qcamera_api_result_t));
3521             result.status = NO_ERROR;
3522             result.request_api = QCAMERA_SM_EVT_STOP_AUTO_FOCUS;
3523             result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
3524             signalAPIResult(&result);
3525         }
3526         break;
3527     case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
3528     case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
3529         if (focus_data.focus_state == CAM_AF_FOCUSED ||
3530             focus_data.focus_state == CAM_AF_NOT_FOCUSED) {
3531             // update focus distance
3532             mParameters.updateFocusDistances(&focus_data.focus_dist);
3533 
3534             ret = sendEvtNotify(CAMERA_MSG_FOCUS,
3535                   (focus_data.focus_state == CAM_AF_FOCUSED)? true : false,
3536                   0);
3537         }
3538         ret = sendEvtNotify(CAMERA_MSG_FOCUS_MOVE,
3539                 (focus_data.focus_state == CAM_AF_SCANNING)? true : false,
3540                 0);
3541         break;
3542     case CAM_FOCUS_MODE_INFINITY:
3543     case CAM_FOCUS_MODE_FIXED:
3544     case CAM_FOCUS_MODE_EDOF:
3545     default:
3546         CDBG_HIGH("%s: no ops for autofocus event in focusmode %d", __func__, focusMode);
3547         break;
3548     }
3549 
3550     CDBG_HIGH("%s: X",__func__);
3551     return ret;
3552 }
3553 
3554 /*===========================================================================
3555  * FUNCTION   : processZoomEvent
3556  *
3557  * DESCRIPTION: process zoom event
3558  *
3559  * PARAMETERS :
3560  *   @crop_info : crop info as a result of zoom operation
3561  *
3562  * RETURN     : int32_t type of status
3563  *              NO_ERROR  -- success
3564  *              none-zero failure code
3565  *==========================================================================*/
processZoomEvent(cam_crop_data_t & crop_info)3566 int32_t QCamera2HardwareInterface::processZoomEvent(cam_crop_data_t &crop_info)
3567 {
3568     int32_t ret = NO_ERROR;
3569 
3570     for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
3571         if (m_channels[i] != NULL) {
3572             ret = m_channels[i]->processZoomDone(mPreviewWindow, crop_info);
3573         }
3574     }
3575     return ret;
3576 }
3577 
3578 /*===========================================================================
3579  * FUNCTION   : processHDRData
3580  *
3581  * DESCRIPTION: process HDR scene events
3582  *
3583  * PARAMETERS :
3584  *   @hdr_scene : HDR scene event data
3585  *
3586  * RETURN     : int32_t type of status
3587  *              NO_ERROR  -- success
3588  *              none-zero failure code
3589  *==========================================================================*/
processHDRData(cam_asd_hdr_scene_data_t hdr_scene)3590 int32_t QCamera2HardwareInterface::processHDRData(cam_asd_hdr_scene_data_t hdr_scene)
3591 {
3592     int rc = NO_ERROR;
3593 
3594 #ifndef VANILLA_HAL
3595     if (hdr_scene.is_hdr_scene &&
3596       (hdr_scene.hdr_confidence > HDR_CONFIDENCE_THRESHOLD) &&
3597       mParameters.isAutoHDREnabled()) {
3598         m_HDRSceneEnabled = true;
3599     } else {
3600         m_HDRSceneEnabled = false;
3601     }
3602     pthread_mutex_lock(&m_parm_lock);
3603     mParameters.setHDRSceneEnable(m_HDRSceneEnabled);
3604     pthread_mutex_unlock(&m_parm_lock);
3605 
3606     if ( msgTypeEnabled(CAMERA_MSG_META_DATA) ) {
3607 
3608         size_t data_len = sizeof(int);
3609         size_t buffer_len = 1 *sizeof(int)       //meta type
3610                           + 1 *sizeof(int)       //data len
3611                           + 1 *sizeof(int);      //data
3612         camera_memory_t *hdrBuffer = mGetMemory(-1,
3613                                                  buffer_len,
3614                                                  1,
3615                                                  mCallbackCookie);
3616         if ( NULL == hdrBuffer ) {
3617             ALOGE("%s: Not enough memory for auto HDR data",
3618                   __func__);
3619             return NO_MEMORY;
3620         }
3621 
3622         int *pHDRData = (int *)hdrBuffer->data;
3623         if (pHDRData == NULL) {
3624             ALOGE("%s: memory data ptr is NULL", __func__);
3625             return UNKNOWN_ERROR;
3626         }
3627 
3628         pHDRData[0] = CAMERA_META_DATA_HDR;
3629         pHDRData[1] = data_len;
3630         pHDRData[2] = m_HDRSceneEnabled;
3631 
3632         qcamera_callback_argm_t cbArg;
3633         memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
3634         cbArg.cb_type = QCAMERA_DATA_CALLBACK;
3635         cbArg.msg_type = CAMERA_MSG_META_DATA;
3636         cbArg.data = hdrBuffer;
3637         cbArg.user_data = hdrBuffer;
3638         cbArg.cookie = this;
3639         cbArg.release_cb = releaseCameraMemory;
3640         rc = m_cbNotifier.notifyCallback(cbArg);
3641         if (rc != NO_ERROR) {
3642             ALOGE("%s: fail sending auto HDR notification", __func__);
3643             hdrBuffer->release(hdrBuffer);
3644         }
3645     }
3646 
3647     ALOGE("%s : hdr_scene_data: processHDRData: %d %f",
3648           __func__,
3649           hdr_scene.is_hdr_scene,
3650           hdr_scene.hdr_confidence);
3651 
3652 #endif
3653   return rc;
3654 }
3655 
3656 /*===========================================================================
3657  * FUNCTION   : processPrepSnapshotDone
3658  *
3659  * DESCRIPTION: process prep snapshot done event
3660  *
3661  * PARAMETERS :
3662  *   @prep_snapshot_state  : state of prepare snapshot done. In other words,
3663  *                           i.e. whether need future frames for capture.
3664  *
3665  * RETURN     : int32_t type of status
3666  *              NO_ERROR  -- success
3667  *              none-zero failure code
3668  *==========================================================================*/
processPrepSnapshotDoneEvent(cam_prep_snapshot_state_t prep_snapshot_state)3669 int32_t QCamera2HardwareInterface::processPrepSnapshotDoneEvent(
3670                         cam_prep_snapshot_state_t prep_snapshot_state)
3671 {
3672     int32_t ret = NO_ERROR;
3673 
3674     if (m_channels[QCAMERA_CH_TYPE_ZSL] &&
3675         prep_snapshot_state == NEED_FUTURE_FRAME) {
3676         CDBG_HIGH("%s: already handled in mm-camera-intf, no ops here", __func__);
3677         if (isRetroPicture()) {
3678             mParameters.setAecLock("true");
3679             mParameters.commitParameters();
3680             m_bLedAfAecLock = TRUE;
3681         }
3682     }
3683     return ret;
3684 }
3685 
3686 /*===========================================================================
3687  * FUNCTION   : processASDUpdate
3688  *
3689  * DESCRIPTION: process ASD update event
3690  *
3691  * PARAMETERS :
3692  *   @scene: selected scene mode
3693  *
3694  * RETURN     : int32_t type of status
3695  *              NO_ERROR  -- success
3696  *              none-zero failure code
3697  *==========================================================================*/
processASDUpdate(cam_auto_scene_t scene)3698 int32_t QCamera2HardwareInterface::processASDUpdate(cam_auto_scene_t scene)
3699 {
3700     //set ASD parameter
3701     mParameters.set(QCameraParameters::KEY_SELECTED_AUTO_SCENE, mParameters.getASDStateString(scene));
3702 
3703     size_t data_len = sizeof(cam_auto_scene_t);
3704     size_t buffer_len = 1 *sizeof(int)       //meta type
3705                       + 1 *sizeof(int)       //data len
3706                       + data_len;            //data
3707     camera_memory_t *asdBuffer = mGetMemory(-1,
3708                                              buffer_len,
3709                                              1,
3710                                              mCallbackCookie);
3711     if ( NULL == asdBuffer ) {
3712         ALOGE("%s: Not enough memory for histogram data", __func__);
3713         return NO_MEMORY;
3714     }
3715 
3716     int *pASDData = (int *)asdBuffer->data;
3717     if (pASDData == NULL) {
3718         ALOGE("%s: memory data ptr is NULL", __func__);
3719         return UNKNOWN_ERROR;
3720     }
3721 
3722 #ifndef VANILLA_HAL
3723     pASDData[0] = CAMERA_META_DATA_ASD;
3724     pASDData[1] = data_len;
3725     pASDData[2] = scene;
3726 
3727     qcamera_callback_argm_t cbArg;
3728     memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
3729     cbArg.cb_type = QCAMERA_DATA_CALLBACK;
3730     cbArg.msg_type = CAMERA_MSG_META_DATA;
3731     cbArg.data = asdBuffer;
3732     cbArg.user_data = asdBuffer;
3733     cbArg.cookie = this;
3734     cbArg.release_cb = releaseCameraMemory;
3735     int32_t rc = m_cbNotifier.notifyCallback(cbArg);
3736     if (rc != NO_ERROR) {
3737         ALOGE("%s: fail sending notification", __func__);
3738         asdBuffer->release(asdBuffer);
3739     }
3740 #endif
3741     return NO_ERROR;
3742 
3743 }
3744 
3745 
3746 /*===========================================================================
3747  * FUNCTION   : processJpegNotify
3748  *
3749  * DESCRIPTION: process jpeg event
3750  *
3751  * PARAMETERS :
3752  *   @jpeg_evt: ptr to jpeg event payload
3753  *
3754  * RETURN     : int32_t type of status
3755  *              NO_ERROR  -- success
3756  *              none-zero failure code
3757  *==========================================================================*/
processJpegNotify(qcamera_jpeg_evt_payload_t * jpeg_evt)3758 int32_t QCamera2HardwareInterface::processJpegNotify(qcamera_jpeg_evt_payload_t *jpeg_evt)
3759 {
3760     return m_postprocessor.processJpegEvt(jpeg_evt);
3761 }
3762 
3763 /*===========================================================================
3764  * FUNCTION   : lockAPI
3765  *
3766  * DESCRIPTION: lock to process API
3767  *
3768  * PARAMETERS : none
3769  *
3770  * RETURN     : none
3771  *==========================================================================*/
lockAPI()3772 void QCamera2HardwareInterface::lockAPI()
3773 {
3774     pthread_mutex_lock(&m_lock);
3775 }
3776 
3777 /*===========================================================================
3778  * FUNCTION   : waitAPIResult
3779  *
3780  * DESCRIPTION: wait for API result coming back. This is a blocking call, it will
3781  *              return only cerntain API event type arrives
3782  *
3783  * PARAMETERS :
3784  *   @api_evt : API event type
3785  *
3786  * RETURN     : none
3787  *==========================================================================*/
waitAPIResult(qcamera_sm_evt_enum_t api_evt,qcamera_api_result_t * apiResult)3788 void QCamera2HardwareInterface::waitAPIResult(qcamera_sm_evt_enum_t api_evt,
3789         qcamera_api_result_t *apiResult)
3790 {
3791     CDBG("%s: wait for API result of evt (%d)", __func__, api_evt);
3792     int resultReceived = 0;
3793     while  (!resultReceived) {
3794         pthread_cond_wait(&m_cond, &m_lock);
3795         if (m_apiResultList != NULL) {
3796             api_result_list *apiResultList = m_apiResultList;
3797             api_result_list *apiResultListPrevious = m_apiResultList;
3798             while (apiResultList != NULL) {
3799                 if (apiResultList->result.request_api == api_evt) {
3800                     resultReceived = 1;
3801                     *apiResult = apiResultList->result;
3802                     apiResultListPrevious->next = apiResultList->next;
3803                     if (apiResultList == m_apiResultList) {
3804                         m_apiResultList = apiResultList->next;
3805                     }
3806                     free(apiResultList);
3807                     break;
3808                 }
3809                 else {
3810                     apiResultListPrevious = apiResultList;
3811                     apiResultList = apiResultList->next;
3812                 }
3813             }
3814         }
3815     }
3816     CDBG("%s: return (%d) from API result wait for evt (%d)",
3817           __func__, apiResult->status, api_evt);
3818 }
3819 
3820 
3821 /*===========================================================================
3822  * FUNCTION   : unlockAPI
3823  *
3824  * DESCRIPTION: API processing is done, unlock
3825  *
3826  * PARAMETERS : none
3827  *
3828  * RETURN     : none
3829  *==========================================================================*/
unlockAPI()3830 void QCamera2HardwareInterface::unlockAPI()
3831 {
3832     pthread_mutex_unlock(&m_lock);
3833 }
3834 
3835 /*===========================================================================
3836  * FUNCTION   : signalAPIResult
3837  *
3838  * DESCRIPTION: signal condition viarable that cerntain API event type arrives
3839  *
3840  * PARAMETERS :
3841  *   @result  : API result
3842  *
3843  * RETURN     : none
3844  *==========================================================================*/
signalAPIResult(qcamera_api_result_t * result)3845 void QCamera2HardwareInterface::signalAPIResult(qcamera_api_result_t *result)
3846 {
3847 
3848     pthread_mutex_lock(&m_lock);
3849     api_result_list *apiResult = (api_result_list *)malloc(sizeof(api_result_list));
3850     if (apiResult == NULL) {
3851         ALOGE("%s: ERROR: malloc for api result failed", __func__);
3852         ALOGE("%s: ERROR: api thread will wait forever fot this lost result", __func__);
3853         goto malloc_failed;
3854     }
3855     apiResult->result = *result;
3856     apiResult->next = NULL;
3857     if (m_apiResultList == NULL) m_apiResultList = apiResult;
3858     else {
3859         api_result_list *apiResultList = m_apiResultList;
3860         while(apiResultList->next != NULL) apiResultList = apiResultList->next;
3861         apiResultList->next = apiResult;
3862     }
3863 malloc_failed:
3864     pthread_cond_broadcast(&m_cond);
3865     pthread_mutex_unlock(&m_lock);
3866 }
3867 
3868 /*===========================================================================
3869  * FUNCTION   : signalEvtResult
3870  *
3871  * DESCRIPTION: signal condition variable that certain event was processed
3872  *
3873  * PARAMETERS :
3874  *   @result  : Event result
3875  *
3876  * RETURN     : none
3877  *==========================================================================*/
signalEvtResult(qcamera_api_result_t * result)3878 void QCamera2HardwareInterface::signalEvtResult(qcamera_api_result_t *result)
3879 {
3880     pthread_mutex_lock(&m_evtLock);
3881     m_evtResult = *result;
3882     pthread_cond_signal(&m_evtCond);
3883     pthread_mutex_unlock(&m_evtLock);
3884 }
3885 
prepareRawStream(QCameraChannel * curChannel)3886 int32_t QCamera2HardwareInterface::prepareRawStream(QCameraChannel *curChannel)
3887 {
3888     int32_t rc = NO_ERROR;
3889     cam_dimension_t str_dim,max_dim;
3890     QCameraChannel *pChannel;
3891 
3892     max_dim.width = 0;
3893     max_dim.height = 0;
3894 
3895     for (int j = 0; j < QCAMERA_CH_TYPE_MAX; j++) {
3896         if (m_channels[j] != NULL) {
3897             pChannel = m_channels[j];
3898             for (int i = 0; i < pChannel->getNumOfStreams();i++) {
3899                 QCameraStream *pStream = pChannel->getStreamByIndex(i);
3900                 if (pStream != NULL) {
3901                     if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
3902                         continue;
3903                     }
3904                     pStream->getFrameDimension(str_dim);
3905                     if (str_dim.width > max_dim.width) {
3906                         max_dim.width = str_dim.width;
3907                     }
3908                     if (str_dim.height > max_dim.height) {
3909                         max_dim.height = str_dim.height;
3910                     }
3911                 }
3912             }
3913         }
3914     }
3915 
3916     for (int i = 0; i < curChannel->getNumOfStreams();i++) {
3917         QCameraStream *pStream = curChannel->getStreamByIndex(i);
3918         if (pStream != NULL) {
3919             if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
3920                 continue;
3921             }
3922             pStream->getFrameDimension(str_dim);
3923             if (str_dim.width > max_dim.width) {
3924                 max_dim.width = str_dim.width;
3925             }
3926             if (str_dim.height > max_dim.height) {
3927                 max_dim.height = str_dim.height;
3928             }
3929         }
3930     }
3931     rc = mParameters.updateRAW(max_dim);
3932     return rc;
3933 }
3934 /*===========================================================================
3935  * FUNCTION   : addStreamToChannel
3936  *
3937  * DESCRIPTION: add a stream into a channel
3938  *
3939  * PARAMETERS :
3940  *   @pChannel   : ptr to channel obj
3941  *   @streamType : type of stream to be added
3942  *   @streamCB   : callback of stream
3943  *   @userData   : user data ptr to callback
3944  *
3945  * RETURN     : int32_t type of status
3946  *              NO_ERROR  -- success
3947  *              none-zero failure code
3948  *==========================================================================*/
addStreamToChannel(QCameraChannel * pChannel,cam_stream_type_t streamType,stream_cb_routine streamCB,void * userData)3949 int32_t QCamera2HardwareInterface::addStreamToChannel(QCameraChannel *pChannel,
3950                                                       cam_stream_type_t streamType,
3951                                                       stream_cb_routine streamCB,
3952                                                       void *userData)
3953 {
3954     int32_t rc = NO_ERROR;
3955 
3956     if (streamType == CAM_STREAM_TYPE_RAW) {
3957         prepareRawStream(pChannel);
3958     }
3959     QCameraHeapMemory *pStreamInfo = allocateStreamInfoBuf(streamType);
3960     if (pStreamInfo == NULL) {
3961         ALOGE("%s: no mem for stream info buf", __func__);
3962         return NO_MEMORY;
3963     }
3964     uint8_t minStreamBufNum = getBufNumRequired(streamType);
3965     bool bDynAllocBuf = false;
3966     if (isZSLMode() && streamType == CAM_STREAM_TYPE_SNAPSHOT) {
3967         bDynAllocBuf = true;
3968     }
3969 
3970     if ( ( streamType == CAM_STREAM_TYPE_SNAPSHOT ||
3971             streamType == CAM_STREAM_TYPE_POSTVIEW ||
3972             streamType == CAM_STREAM_TYPE_METADATA ||
3973             streamType == CAM_STREAM_TYPE_RAW) &&
3974             !isZSLMode() &&
3975             !isLongshotEnabled() &&
3976             !mParameters.getRecordingHintValue()) {
3977         rc = pChannel->addStream(*this,
3978                 pStreamInfo,
3979                 minStreamBufNum,
3980                 &gCamCaps[mCameraId]->padding_info,
3981                 streamCB, userData,
3982                 bDynAllocBuf,
3983                 true);
3984 
3985         // Queue buffer allocation for Snapshot and Metadata streams
3986         if ( !rc ) {
3987             DefferWorkArgs args;
3988             DefferAllocBuffArgs allocArgs;
3989 
3990             memset(&args, 0, sizeof(DefferWorkArgs));
3991             memset(&allocArgs, 0, sizeof(DefferAllocBuffArgs));
3992             allocArgs.type = streamType;
3993             allocArgs.ch = pChannel;
3994             args.allocArgs = allocArgs;
3995 
3996             if (streamType == CAM_STREAM_TYPE_SNAPSHOT) {
3997                 mSnapshotJob = queueDefferedWork(CMD_DEFF_ALLOCATE_BUFF,
3998                         args);
3999 
4000                 if ( mSnapshotJob == -1) {
4001                     rc = UNKNOWN_ERROR;
4002                 }
4003             } else if (streamType == CAM_STREAM_TYPE_METADATA) {
4004                 mMetadataJob = queueDefferedWork(CMD_DEFF_ALLOCATE_BUFF,
4005                         args);
4006 
4007                 if ( mMetadataJob == -1) {
4008                     rc = UNKNOWN_ERROR;
4009                 }
4010             } else if (streamType == CAM_STREAM_TYPE_RAW) {
4011                 mRawdataJob = queueDefferedWork(CMD_DEFF_ALLOCATE_BUFF,
4012                         args);
4013 
4014                 if ( mRawdataJob == -1) {
4015                     rc = UNKNOWN_ERROR;
4016                 }
4017             }
4018         }
4019     } else {
4020         rc = pChannel->addStream(*this,
4021                 pStreamInfo,
4022                 minStreamBufNum,
4023                 &gCamCaps[mCameraId]->padding_info,
4024                 streamCB, userData,
4025                 bDynAllocBuf,
4026                 false);
4027     }
4028 
4029     if (rc != NO_ERROR) {
4030         ALOGE("%s: add stream type (%d) failed, ret = %d",
4031               __func__, streamType, rc);
4032         pStreamInfo->deallocate();
4033         delete pStreamInfo;
4034         return rc;
4035     }
4036 
4037     return rc;
4038 }
4039 
4040 /*===========================================================================
4041  * FUNCTION   : addPreviewChannel
4042  *
4043  * DESCRIPTION: add a preview channel that contains a preview stream
4044  *
4045  * PARAMETERS : none
4046  *
4047  * RETURN     : int32_t type of status
4048  *              NO_ERROR  -- success
4049  *              none-zero failure code
4050  *==========================================================================*/
addPreviewChannel()4051 int32_t QCamera2HardwareInterface::addPreviewChannel()
4052 {
4053     int32_t rc = NO_ERROR;
4054     QCameraChannel *pChannel = NULL;
4055 
4056     if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
4057         // Using the no preview torch WA it is possible
4058         // to already have a preview channel present before
4059         // start preview gets called.
4060         ALOGD(" %s : Preview Channel already added!", __func__);
4061         return NO_ERROR;
4062     }
4063 
4064     pChannel = new QCameraChannel(mCameraHandle->camera_handle,
4065                                   mCameraHandle->ops);
4066     if (NULL == pChannel) {
4067         ALOGE("%s: no mem for preview channel", __func__);
4068         return NO_MEMORY;
4069     }
4070 
4071     // preview only channel, don't need bundle attr and cb
4072     rc = pChannel->init(NULL, NULL, NULL);
4073     if (rc != NO_ERROR) {
4074         ALOGE("%s: init preview channel failed, ret = %d", __func__, rc);
4075         delete pChannel;
4076         return rc;
4077     }
4078 
4079     // meta data stream always coexists with preview if applicable
4080     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
4081                             metadata_stream_cb_routine, this);
4082     if (rc != NO_ERROR) {
4083         ALOGE("%s: add metadata stream failed, ret = %d", __func__, rc);
4084         delete pChannel;
4085         return rc;
4086     }
4087 
4088     if (isRdiMode()) {
4089         CDBG_HIGH("RDI_DEBUG %s[%d]: Add stream to channel", __func__, __LINE__);
4090         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
4091                                 rdi_mode_stream_cb_routine, this);
4092     } else {
4093         if (isNoDisplayMode()) {
4094             rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
4095                                     nodisplay_preview_stream_cb_routine, this);
4096         } else {
4097             rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
4098                                     preview_stream_cb_routine, this);
4099         }
4100     }
4101     if (rc != NO_ERROR) {
4102         ALOGE("%s: add preview stream failed, ret = %d", __func__, rc);
4103         delete pChannel;
4104         return rc;
4105     }
4106 
4107     m_channels[QCAMERA_CH_TYPE_PREVIEW] = pChannel;
4108     return rc;
4109 }
4110 
4111 /*===========================================================================
4112  * FUNCTION   : addVideoChannel
4113  *
4114  * DESCRIPTION: add a video channel that contains a video stream
4115  *
4116  * PARAMETERS : none
4117  *
4118  * RETURN     : int32_t type of status
4119  *              NO_ERROR  -- success
4120  *              none-zero failure code
4121  *==========================================================================*/
addVideoChannel()4122 int32_t QCamera2HardwareInterface::addVideoChannel()
4123 {
4124     int32_t rc = NO_ERROR;
4125     QCameraVideoChannel *pChannel = NULL;
4126 
4127     if (m_channels[QCAMERA_CH_TYPE_VIDEO] != NULL) {
4128         // if we had video channel before, delete it first
4129         delete m_channels[QCAMERA_CH_TYPE_VIDEO];
4130         m_channels[QCAMERA_CH_TYPE_VIDEO] = NULL;
4131     }
4132 
4133     pChannel = new QCameraVideoChannel(mCameraHandle->camera_handle,
4134                                        mCameraHandle->ops);
4135     if (NULL == pChannel) {
4136         ALOGE("%s: no mem for video channel", __func__);
4137         return NO_MEMORY;
4138     }
4139 
4140     // preview only channel, don't need bundle attr and cb
4141     rc = pChannel->init(NULL, NULL, NULL);
4142     if (rc != 0) {
4143         ALOGE("%s: init video channel failed, ret = %d", __func__, rc);
4144         delete pChannel;
4145         return rc;
4146     }
4147 
4148     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_VIDEO,
4149                             video_stream_cb_routine, this);
4150     if (rc != NO_ERROR) {
4151         ALOGE("%s: add video stream failed, ret = %d", __func__, rc);
4152         delete pChannel;
4153         return rc;
4154     }
4155 
4156     m_channels[QCAMERA_CH_TYPE_VIDEO] = pChannel;
4157     return rc;
4158 }
4159 
4160 /*===========================================================================
4161  * FUNCTION   : addSnapshotChannel
4162  *
4163  * DESCRIPTION: add a snapshot channel that contains a snapshot stream
4164  *
4165  * PARAMETERS : none
4166  *
4167  * RETURN     : int32_t type of status
4168  *              NO_ERROR  -- success
4169  *              none-zero failure code
4170  * NOTE       : Add this channel for live snapshot usecase. Regular capture will
4171  *              use addCaptureChannel.
4172  *==========================================================================*/
addSnapshotChannel()4173 int32_t QCamera2HardwareInterface::addSnapshotChannel()
4174 {
4175     int32_t rc = NO_ERROR;
4176     QCameraChannel *pChannel = NULL;
4177 
4178     if (m_channels[QCAMERA_CH_TYPE_SNAPSHOT] != NULL) {
4179         // if we had ZSL channel before, delete it first
4180         delete m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
4181         m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = NULL;
4182     }
4183 
4184     pChannel = new QCameraChannel(mCameraHandle->camera_handle,
4185                                   mCameraHandle->ops);
4186     if (NULL == pChannel) {
4187         ALOGE("%s: no mem for snapshot channel", __func__);
4188         return NO_MEMORY;
4189     }
4190 
4191     rc = pChannel->init(NULL, NULL, NULL);
4192     if (rc != NO_ERROR) {
4193         ALOGE("%s: init snapshot channel failed, ret = %d", __func__, rc);
4194         delete pChannel;
4195         return rc;
4196     }
4197 
4198     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
4199                             snapshot_stream_cb_routine, this);
4200     if (rc != NO_ERROR) {
4201         ALOGE("%s: add snapshot stream failed, ret = %d", __func__, rc);
4202         delete pChannel;
4203         return rc;
4204     }
4205 
4206     m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = pChannel;
4207     return rc;
4208 }
4209 
4210 /*===========================================================================
4211  * FUNCTION   : addRawChannel
4212  *
4213  * DESCRIPTION: add a raw channel that contains a raw image stream
4214  *
4215  * PARAMETERS : none
4216  *
4217  * RETURN     : int32_t type of status
4218  *              NO_ERROR  -- success
4219  *              none-zero failure code
4220  *==========================================================================*/
addRawChannel()4221 int32_t QCamera2HardwareInterface::addRawChannel()
4222 {
4223     int32_t rc = NO_ERROR;
4224     QCameraChannel *pChannel = NULL;
4225 
4226     if (m_channels[QCAMERA_CH_TYPE_RAW] != NULL) {
4227         // if we had raw channel before, delete it first
4228         delete m_channels[QCAMERA_CH_TYPE_RAW];
4229         m_channels[QCAMERA_CH_TYPE_RAW] = NULL;
4230     }
4231 
4232     pChannel = new QCameraChannel(mCameraHandle->camera_handle,
4233                                   mCameraHandle->ops);
4234     if (NULL == pChannel) {
4235         ALOGE("%s: no mem for raw channel", __func__);
4236         return NO_MEMORY;
4237     }
4238 
4239     rc = pChannel->init(NULL, NULL, NULL);
4240     if (rc != NO_ERROR) {
4241         ALOGE("%s: init raw channel failed, ret = %d", __func__, rc);
4242         delete pChannel;
4243         return rc;
4244     }
4245 
4246     // meta data stream always coexists with snapshot in regular RAW capture case
4247     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
4248                             metadata_stream_cb_routine, this);
4249     if (rc != NO_ERROR) {
4250         ALOGE("%s: add metadata stream failed, ret = %d", __func__, rc);
4251         delete pChannel;
4252         return rc;
4253     }
4254     waitDefferedWork(mMetadataJob);
4255 
4256     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
4257                             raw_stream_cb_routine, this);
4258     if (rc != NO_ERROR) {
4259         ALOGE("%s: add snapshot stream failed, ret = %d", __func__, rc);
4260         delete pChannel;
4261         return rc;
4262     }
4263     waitDefferedWork(mRawdataJob);
4264     m_channels[QCAMERA_CH_TYPE_RAW] = pChannel;
4265     return rc;
4266 }
4267 
4268 /*===========================================================================
4269  * FUNCTION   : addZSLChannel
4270  *
4271  * DESCRIPTION: add a ZSL channel that contains a preview stream and
4272  *              a snapshot stream
4273  *
4274  * PARAMETERS : none
4275  *
4276  * RETURN     : int32_t type of status
4277  *              NO_ERROR  -- success
4278  *              none-zero failure code
4279  *==========================================================================*/
addZSLChannel()4280 int32_t QCamera2HardwareInterface::addZSLChannel()
4281 {
4282     int32_t rc = NO_ERROR;
4283     QCameraPicChannel *pChannel = NULL;
4284     char value[PROPERTY_VALUE_MAX];
4285     bool raw_yuv = false;
4286 
4287     if (m_channels[QCAMERA_CH_TYPE_ZSL] != NULL) {
4288         // if we had ZSL channel before, delete it first
4289         delete m_channels[QCAMERA_CH_TYPE_ZSL];
4290         m_channels[QCAMERA_CH_TYPE_ZSL] = NULL;
4291     }
4292 
4293      if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
4294         delete m_channels[QCAMERA_CH_TYPE_PREVIEW];
4295         m_channels[QCAMERA_CH_TYPE_PREVIEW] = NULL;
4296     }
4297 
4298     pChannel = new QCameraPicChannel(mCameraHandle->camera_handle,
4299                                      mCameraHandle->ops);
4300     if (NULL == pChannel) {
4301         ALOGE("%s: no mem for ZSL channel", __func__);
4302         return NO_MEMORY;
4303     }
4304 
4305     // ZSL channel, init with bundle attr and cb
4306     mm_camera_channel_attr_t attr;
4307     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
4308     if (mParameters.isSceneSelectionEnabled()) {
4309         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
4310     } else {
4311         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
4312     }
4313     attr.look_back = mParameters.getZSLBackLookCount();
4314     attr.post_frame_skip = mParameters.getZSLBurstInterval();
4315     attr.water_mark = mParameters.getZSLQueueDepth();
4316     attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
4317     rc = pChannel->init(&attr,
4318                         zsl_channel_cb,
4319                         this);
4320     if (rc != 0) {
4321         ALOGE("%s: init ZSL channel failed, ret = %d", __func__, rc);
4322         delete pChannel;
4323         return rc;
4324     }
4325 
4326     // meta data stream always coexists with preview if applicable
4327     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
4328                             metadata_stream_cb_routine, this);
4329     if (rc != NO_ERROR) {
4330         ALOGE("%s: add metadata stream failed, ret = %d", __func__, rc);
4331         delete pChannel;
4332         return rc;
4333     }
4334 
4335     if (isNoDisplayMode()) {
4336         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
4337                                 nodisplay_preview_stream_cb_routine, this);
4338     } else {
4339         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
4340                                 preview_stream_cb_routine, this);
4341     }
4342     if (rc != NO_ERROR) {
4343         ALOGE("%s: add preview stream failed, ret = %d", __func__, rc);
4344         delete pChannel;
4345         return rc;
4346     }
4347 
4348     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
4349                             NULL, this);
4350     if (rc != NO_ERROR) {
4351         ALOGE("%s: add snapshot stream failed, ret = %d", __func__, rc);
4352         delete pChannel;
4353         return rc;
4354     }
4355 
4356     property_get("persist.camera.raw_yuv", value, "0");
4357     raw_yuv = atoi(value) > 0 ? true : false;
4358     if ( raw_yuv ) {
4359         rc = addStreamToChannel(pChannel,
4360                                 CAM_STREAM_TYPE_RAW,
4361                                 NULL,
4362                                 this);
4363         if (rc != NO_ERROR) {
4364             ALOGE("%s: add raw stream failed, ret = %d", __func__, rc);
4365             delete pChannel;
4366             return rc;
4367         }
4368     }
4369 
4370     m_channels[QCAMERA_CH_TYPE_ZSL] = pChannel;
4371     return rc;
4372 }
4373 
4374 /*===========================================================================
4375  * FUNCTION   : addCaptureChannel
4376  *
4377  * DESCRIPTION: add a capture channel that contains a snapshot stream
4378  *              and a postview stream
4379  *
4380  * PARAMETERS : none
4381  *
4382  * RETURN     : int32_t type of status
4383  *              NO_ERROR  -- success
4384  *              none-zero failure code
4385  * NOTE       : Add this channel for regular capture usecase.
4386  *              For Live snapshot usecase, use addSnapshotChannel.
4387  *==========================================================================*/
addCaptureChannel()4388 int32_t QCamera2HardwareInterface::addCaptureChannel()
4389 {
4390     int32_t rc = NO_ERROR;
4391     QCameraPicChannel *pChannel = NULL;
4392     char value[PROPERTY_VALUE_MAX];
4393     bool raw_yuv = false;
4394 
4395     if (m_channels[QCAMERA_CH_TYPE_CAPTURE] != NULL) {
4396         delete m_channels[QCAMERA_CH_TYPE_CAPTURE];
4397         m_channels[QCAMERA_CH_TYPE_CAPTURE] = NULL;
4398     }
4399 
4400     pChannel = new QCameraPicChannel(mCameraHandle->camera_handle,
4401                                   mCameraHandle->ops);
4402     if (NULL == pChannel) {
4403         ALOGE("%s: no mem for capture channel", __func__);
4404         return NO_MEMORY;
4405     }
4406 
4407     // Capture channel, only need snapshot and postview streams start together
4408     mm_camera_channel_attr_t attr;
4409     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
4410     if ( mLongshotEnabled ) {
4411         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
4412         attr.look_back = mParameters.getZSLBackLookCount();
4413         attr.water_mark = mParameters.getZSLQueueDepth();
4414     } else {
4415         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
4416     }
4417     attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
4418 
4419     rc = pChannel->init(&attr,
4420                         capture_channel_cb_routine,
4421                         this);
4422     if (rc != NO_ERROR) {
4423         ALOGE("%s: init capture channel failed, ret = %d", __func__, rc);
4424         delete pChannel;
4425         return rc;
4426     }
4427 
4428     // meta data stream always coexists with snapshot in regular capture case
4429     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
4430                             metadata_stream_cb_routine, this);
4431     if (rc != NO_ERROR) {
4432         ALOGE("%s: add metadata stream failed, ret = %d", __func__, rc);
4433         delete pChannel;
4434         return rc;
4435     }
4436 
4437     if (!mLongshotEnabled) {
4438         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_POSTVIEW,
4439                                 NULL, this);
4440 
4441         if (rc != NO_ERROR) {
4442             ALOGE("%s: add postview stream failed, ret = %d", __func__, rc);
4443             delete pChannel;
4444             return rc;
4445         }
4446     } else {
4447         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
4448                                 preview_stream_cb_routine, this);
4449 
4450         if (rc != NO_ERROR) {
4451             ALOGE("%s: add preview stream failed, ret = %d", __func__, rc);
4452             delete pChannel;
4453             return rc;
4454         }
4455     }
4456 
4457     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
4458                             NULL, this);
4459     if (rc != NO_ERROR) {
4460         ALOGE("%s: add snapshot stream failed, ret = %d", __func__, rc);
4461         delete pChannel;
4462         return rc;
4463     }
4464 
4465     property_get("persist.camera.raw_yuv", value, "0");
4466     raw_yuv = atoi(value) > 0 ? true : false;
4467     if ( raw_yuv ) {
4468         rc = addStreamToChannel(pChannel,
4469                                 CAM_STREAM_TYPE_RAW,
4470                                 snapshot_raw_stream_cb_routine,
4471                                 this);
4472         if (rc != NO_ERROR) {
4473             ALOGE("%s: add raw stream failed, ret = %d", __func__, rc);
4474             delete pChannel;
4475             return rc;
4476         }
4477     }
4478 
4479     m_channels[QCAMERA_CH_TYPE_CAPTURE] = pChannel;
4480     return rc;
4481 }
4482 
4483 /*===========================================================================
4484  * FUNCTION   : addMetaDataChannel
4485  *
4486  * DESCRIPTION: add a meta data channel that contains a metadata stream
4487  *
4488  * PARAMETERS : none
4489  *
4490  * RETURN     : int32_t type of status
4491  *              NO_ERROR  -- success
4492  *              none-zero failure code
4493  *==========================================================================*/
addMetaDataChannel()4494 int32_t QCamera2HardwareInterface::addMetaDataChannel()
4495 {
4496     int32_t rc = NO_ERROR;
4497     QCameraChannel *pChannel = NULL;
4498 
4499     if (m_channels[QCAMERA_CH_TYPE_METADATA] != NULL) {
4500         delete m_channels[QCAMERA_CH_TYPE_METADATA];
4501         m_channels[QCAMERA_CH_TYPE_METADATA] = NULL;
4502     }
4503 
4504     pChannel = new QCameraChannel(mCameraHandle->camera_handle,
4505                                   mCameraHandle->ops);
4506     if (NULL == pChannel) {
4507         ALOGE("%s: no mem for metadata channel", __func__);
4508         return NO_MEMORY;
4509     }
4510 
4511     rc = pChannel->init(NULL,
4512                         NULL,
4513                         NULL);
4514     if (rc != NO_ERROR) {
4515         ALOGE("%s: init metadata channel failed, ret = %d", __func__, rc);
4516         delete pChannel;
4517         return rc;
4518     }
4519 
4520     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
4521                             metadata_stream_cb_routine, this);
4522     if (rc != NO_ERROR) {
4523         ALOGE("%s: add metadata stream failed, ret = %d", __func__, rc);
4524         delete pChannel;
4525         return rc;
4526     }
4527 
4528     m_channels[QCAMERA_CH_TYPE_METADATA] = pChannel;
4529     return rc;
4530 }
4531 
4532 /*===========================================================================
4533  * FUNCTION   : addReprocChannel
4534  *
4535  * DESCRIPTION: add a reprocess channel that will do reprocess on frames
4536  *              coming from input channel
4537  *
4538  * PARAMETERS :
4539  *   @pInputChannel : ptr to input channel whose frames will be post-processed
4540  *
4541  * RETURN     : Ptr to the newly created channel obj. NULL if failed.
4542  *==========================================================================*/
addReprocChannel(QCameraChannel * pInputChannel)4543 QCameraReprocessChannel *QCamera2HardwareInterface::addReprocChannel(
4544                                                       QCameraChannel *pInputChannel)
4545 {
4546     int32_t rc = NO_ERROR;
4547     QCameraReprocessChannel *pChannel = NULL;
4548     const char *effect;
4549 
4550     if (pInputChannel == NULL) {
4551         ALOGE("%s: input channel obj is NULL", __func__);
4552         return NULL;
4553     }
4554 
4555     pChannel = new QCameraReprocessChannel(mCameraHandle->camera_handle,
4556                                            mCameraHandle->ops);
4557     if (NULL == pChannel) {
4558         ALOGE("%s: no mem for reprocess channel", __func__);
4559         return NULL;
4560     }
4561 
4562     // Capture channel, only need snapshot and postview streams start together
4563     mm_camera_channel_attr_t attr;
4564     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
4565     attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
4566     attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
4567     rc = pChannel->init(&attr,
4568                         postproc_channel_cb_routine,
4569                         this);
4570     if (rc != NO_ERROR) {
4571         ALOGE("%s: init reprocess channel failed, ret = %d", __func__, rc);
4572         delete pChannel;
4573         return NULL;
4574     }
4575 
4576     CDBG_HIGH("%s: Before pproc config check, ret = %x", __func__,
4577             gCamCaps[mCameraId]->min_required_pp_mask);
4578 
4579     // pp feature config
4580     cam_pp_feature_config_t pp_config;
4581     memset(&pp_config, 0, sizeof(cam_pp_feature_config_t));
4582     if (mParameters.isZSLMode()) {
4583         if (gCamCaps[mCameraId]->min_required_pp_mask & CAM_QCOM_FEATURE_EFFECT) {
4584             pp_config.feature_mask |= CAM_QCOM_FEATURE_EFFECT;
4585             effect = mParameters.get(CameraParameters::KEY_EFFECT);
4586             pp_config.effect = getEffectValue(effect);
4587         }
4588         if ((gCamCaps[mCameraId]->min_required_pp_mask & CAM_QCOM_FEATURE_SHARPNESS) &&
4589                 !mParameters.isOptiZoomEnabled()) {
4590             pp_config.feature_mask |= CAM_QCOM_FEATURE_SHARPNESS;
4591             pp_config.sharpness = mParameters.getInt(QCameraParameters::KEY_QC_SHARPNESS);
4592         }
4593 
4594         if (gCamCaps[mCameraId]->min_required_pp_mask & CAM_QCOM_FEATURE_CROP) {
4595             pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
4596         }
4597 
4598         if (mParameters.isWNREnabled()) {
4599             pp_config.feature_mask |= CAM_QCOM_FEATURE_DENOISE2D;
4600             pp_config.denoise2d.denoise_enable = 1;
4601             pp_config.denoise2d.process_plates = mParameters.getWaveletDenoiseProcessPlate();
4602         }
4603     }
4604 
4605     if (isCACEnabled()) {
4606         pp_config.feature_mask |= CAM_QCOM_FEATURE_CAC;
4607     }
4608 
4609     if (needRotationReprocess()) {
4610         pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION;
4611         int rotation = getJpegRotation();
4612         if (rotation == 0) {
4613             pp_config.rotation = ROTATE_0;
4614         } else if (rotation == 90) {
4615             pp_config.rotation = ROTATE_90;
4616         } else if (rotation == 180) {
4617             pp_config.rotation = ROTATE_180;
4618         } else if (rotation == 270) {
4619             pp_config.rotation = ROTATE_270;
4620         }
4621     }
4622 
4623     uint8_t minStreamBufNum = getBufNumRequired(CAM_STREAM_TYPE_OFFLINE_PROC);
4624 
4625     if (mParameters.isHDREnabled()){
4626         pp_config.feature_mask |= CAM_QCOM_FEATURE_HDR;
4627         pp_config.hdr_param.hdr_enable = 1;
4628         pp_config.hdr_param.hdr_need_1x = mParameters.isHDR1xFrameEnabled();
4629         pp_config.hdr_param.hdr_mode = CAM_HDR_MODE_MULTIFRAME;
4630     } else {
4631         pp_config.feature_mask &= ~CAM_QCOM_FEATURE_HDR;
4632         pp_config.hdr_param.hdr_enable = 0;
4633     }
4634 
4635     if(needScaleReprocess()){
4636         pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
4637         mParameters.m_reprocScaleParam.getPicSizeFromAPK(
4638               pp_config.scale_param.output_width, pp_config.scale_param.output_height);
4639     }
4640 
4641     CDBG_HIGH("%s: After pproc config check, ret = %x", __func__, pp_config.feature_mask);
4642 
4643     if(mParameters.isUbiFocusEnabled()) {
4644         pp_config.feature_mask |= CAM_QCOM_FEATURE_UBIFOCUS;
4645     } else {
4646         pp_config.feature_mask &= ~CAM_QCOM_FEATURE_UBIFOCUS;
4647     }
4648 
4649     if(mParameters.isChromaFlashEnabled()) {
4650         pp_config.feature_mask |= CAM_QCOM_FEATURE_CHROMA_FLASH;
4651         //TODO: check flash value for captured image, then assign.
4652         pp_config.flash_value = CAM_FLASH_ON;
4653     } else {
4654         pp_config.feature_mask &= ~CAM_QCOM_FEATURE_CHROMA_FLASH;
4655     }
4656 
4657     if(mParameters.isOptiZoomEnabled()) {
4658         pp_config.feature_mask |= CAM_QCOM_FEATURE_OPTIZOOM;
4659         pp_config.zoom_level =
4660                 (uint8_t) mParameters.getInt(CameraParameters::KEY_ZOOM);
4661     } else {
4662         pp_config.feature_mask &= ~CAM_QCOM_FEATURE_OPTIZOOM;
4663     }
4664 
4665     //WNR and HDR happen inline. No extra buffers needed.
4666     uint32_t temp_feature_mask = pp_config.feature_mask;
4667     temp_feature_mask &= ~CAM_QCOM_FEATURE_HDR;
4668     if (temp_feature_mask && mParameters.isHDREnabled()) {
4669         minStreamBufNum = 1 + mParameters.getNumOfExtraHDRInBufsIfNeeded();
4670     }
4671 
4672     // Add non inplace image lib buffers only when ppproc is present,
4673     // becuase pproc is non inplace and input buffers for img lib
4674     // are output for pproc and this number of extra buffers is required
4675     // If pproc is not there, input buffers for imglib are from snapshot stream
4676     uint8_t imglib_extra_bufs = mParameters.getNumOfExtraBuffersForImageProc();
4677     if (temp_feature_mask && imglib_extra_bufs) {
4678         // 1 is added because getNumOfExtraBuffersForImageProc returns extra
4679         // buffers assuming number of capture is already added
4680         minStreamBufNum += imglib_extra_bufs + 1;
4681     }
4682 
4683     bool offlineReproc = isRegularCapture();
4684     rc = pChannel->addReprocStreamsFromSource(*this,
4685                                               pp_config,
4686                                               pInputChannel,
4687                                               minStreamBufNum,
4688                                               mParameters.getNumOfSnapshots(),
4689                                               &gCamCaps[mCameraId]->padding_info,
4690                                               mParameters,
4691                                               mLongshotEnabled,
4692                                               offlineReproc);
4693     if (rc != NO_ERROR) {
4694         delete pChannel;
4695         return NULL;
4696     }
4697 
4698     return pChannel;
4699 }
4700 
4701 /*===========================================================================
4702  * FUNCTION   : addOfflineReprocChannel
4703  *
4704  * DESCRIPTION: add a offline reprocess channel contains one reproc stream,
4705  *              that will do reprocess on frames coming from external images
4706  *
4707  * PARAMETERS :
4708  *   @img_config  : offline reporcess image info
4709  *   @pp_feature  : pp feature config
4710  *
4711  * RETURN     : int32_t type of status
4712  *              NO_ERROR  -- success
4713  *              none-zero failure code
4714  *==========================================================================*/
addOfflineReprocChannel(cam_pp_offline_src_config_t & img_config,cam_pp_feature_config_t & pp_feature,stream_cb_routine stream_cb,void * userdata)4715 QCameraReprocessChannel *QCamera2HardwareInterface::addOfflineReprocChannel(
4716                                             cam_pp_offline_src_config_t &img_config,
4717                                             cam_pp_feature_config_t &pp_feature,
4718                                             stream_cb_routine stream_cb,
4719                                             void *userdata)
4720 {
4721     int32_t rc = NO_ERROR;
4722     QCameraReprocessChannel *pChannel = NULL;
4723 
4724     pChannel = new QCameraReprocessChannel(mCameraHandle->camera_handle,
4725                                            mCameraHandle->ops);
4726     if (NULL == pChannel) {
4727         ALOGE("%s: no mem for reprocess channel", __func__);
4728         return NULL;
4729     }
4730 
4731     rc = pChannel->init(NULL, NULL, NULL);
4732     if (rc != NO_ERROR) {
4733         ALOGE("%s: init reprocess channel failed, ret = %d", __func__, rc);
4734         delete pChannel;
4735         return NULL;
4736     }
4737 
4738     QCameraHeapMemory *pStreamInfo = allocateStreamInfoBuf(CAM_STREAM_TYPE_OFFLINE_PROC);
4739     if (pStreamInfo == NULL) {
4740         ALOGE("%s: no mem for stream info buf", __func__);
4741         delete pChannel;
4742         return NULL;
4743     }
4744 
4745     cam_stream_info_t *streamInfoBuf = (cam_stream_info_t *)pStreamInfo->getPtr(0);
4746     memset(streamInfoBuf, 0, sizeof(cam_stream_info_t));
4747     streamInfoBuf->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC;
4748     streamInfoBuf->fmt = img_config.input_fmt;
4749     streamInfoBuf->dim = img_config.input_dim;
4750     streamInfoBuf->buf_planes = img_config.input_buf_planes;
4751     streamInfoBuf->streaming_mode = CAM_STREAMING_MODE_BURST;
4752     streamInfoBuf->num_of_burst = img_config.num_of_bufs;
4753 
4754     streamInfoBuf->reprocess_config.pp_type = CAM_OFFLINE_REPROCESS_TYPE;
4755     streamInfoBuf->reprocess_config.offline = img_config;
4756     streamInfoBuf->reprocess_config.pp_feature_config = pp_feature;
4757 
4758     rc = pChannel->addStream(*this,
4759                              pStreamInfo, img_config.num_of_bufs,
4760                              &gCamCaps[mCameraId]->padding_info,
4761                              stream_cb, userdata, false);
4762 
4763     if (rc != NO_ERROR) {
4764         ALOGE("%s: add reprocess stream failed, ret = %d", __func__, rc);
4765         pStreamInfo->deallocate();
4766         delete pStreamInfo;
4767         delete pChannel;
4768         return NULL;
4769     }
4770 
4771     return pChannel;
4772 }
4773 
4774 /*===========================================================================
4775  * FUNCTION   : addChannel
4776  *
4777  * DESCRIPTION: add a channel by its type
4778  *
4779  * PARAMETERS :
4780  *   @ch_type : channel type
4781  *
4782  * RETURN     : int32_t type of status
4783  *              NO_ERROR  -- success
4784  *              none-zero failure code
4785  *==========================================================================*/
addChannel(qcamera_ch_type_enum_t ch_type)4786 int32_t QCamera2HardwareInterface::addChannel(qcamera_ch_type_enum_t ch_type)
4787 {
4788     int32_t rc = UNKNOWN_ERROR;
4789     switch (ch_type) {
4790     case QCAMERA_CH_TYPE_ZSL:
4791         rc = addZSLChannel();
4792         break;
4793     case QCAMERA_CH_TYPE_CAPTURE:
4794         rc = addCaptureChannel();
4795         break;
4796     case QCAMERA_CH_TYPE_PREVIEW:
4797         rc = addPreviewChannel();
4798         break;
4799     case QCAMERA_CH_TYPE_VIDEO:
4800         rc = addVideoChannel();
4801         break;
4802     case QCAMERA_CH_TYPE_SNAPSHOT:
4803         rc = addSnapshotChannel();
4804         break;
4805     case QCAMERA_CH_TYPE_RAW:
4806         rc = addRawChannel();
4807         break;
4808     case QCAMERA_CH_TYPE_METADATA:
4809         rc = addMetaDataChannel();
4810         break;
4811     default:
4812         break;
4813     }
4814     return rc;
4815 }
4816 
4817 /*===========================================================================
4818  * FUNCTION   : delChannel
4819  *
4820  * DESCRIPTION: delete a channel by its type
4821  *
4822  * PARAMETERS :
4823  *   @ch_type : channel type
4824  *   @destroy : delete context as well
4825  *
4826  * RETURN     : int32_t type of status
4827  *              NO_ERROR  -- success
4828  *              none-zero failure code
4829  *==========================================================================*/
delChannel(qcamera_ch_type_enum_t ch_type,bool destroy)4830 int32_t QCamera2HardwareInterface::delChannel(qcamera_ch_type_enum_t ch_type,
4831                                               bool destroy)
4832 {
4833     if (m_channels[ch_type] != NULL) {
4834         if (destroy) {
4835             delete m_channels[ch_type];
4836             m_channels[ch_type] = NULL;
4837         } else {
4838             m_channels[ch_type]->deleteChannel();
4839         }
4840     }
4841 
4842     return NO_ERROR;
4843 }
4844 
4845 /*===========================================================================
4846  * FUNCTION   : startChannel
4847  *
4848  * DESCRIPTION: start a channel by its type
4849  *
4850  * PARAMETERS :
4851  *   @ch_type : channel type
4852  *
4853  * RETURN     : int32_t type of status
4854  *              NO_ERROR  -- success
4855  *              none-zero failure code
4856  *==========================================================================*/
startChannel(qcamera_ch_type_enum_t ch_type)4857 int32_t QCamera2HardwareInterface::startChannel(qcamera_ch_type_enum_t ch_type)
4858 {
4859     int32_t rc = UNKNOWN_ERROR;
4860     if (m_channels[ch_type] != NULL) {
4861         rc = m_channels[ch_type]->config();
4862         if (NO_ERROR == rc) {
4863             rc = m_channels[ch_type]->start();
4864         }
4865     }
4866 
4867     return rc;
4868 }
4869 
4870 /*===========================================================================
4871  * FUNCTION   : stopChannel
4872  *
4873  * DESCRIPTION: stop a channel by its type
4874  *
4875  * PARAMETERS :
4876  *   @ch_type : channel type
4877  *
4878  * RETURN     : int32_t type of status
4879  *              NO_ERROR  -- success
4880  *              none-zero failure code
4881  *==========================================================================*/
stopChannel(qcamera_ch_type_enum_t ch_type)4882 int32_t QCamera2HardwareInterface::stopChannel(qcamera_ch_type_enum_t ch_type)
4883 {
4884     int32_t rc = UNKNOWN_ERROR;
4885     if (m_channels[ch_type] != NULL) {
4886         rc = m_channels[ch_type]->stop();
4887     }
4888 
4889     return rc;
4890 }
4891 
4892 /*===========================================================================
4893  * FUNCTION   : preparePreview
4894  *
4895  * DESCRIPTION: add channels needed for preview
4896  *
4897  * PARAMETERS : none
4898  *
4899  * RETURN     : int32_t type of status
4900  *              NO_ERROR  -- success
4901  *              none-zero failure code
4902  *==========================================================================*/
preparePreview()4903 int32_t QCamera2HardwareInterface::preparePreview()
4904 {
4905     int32_t rc = NO_ERROR;
4906 
4907     pthread_mutex_lock(&m_parm_lock);
4908     rc = mParameters.setStreamConfigure(false, false);
4909     if (rc != NO_ERROR) {
4910         ALOGE("%s: setStreamConfigure failed %d", __func__, rc);
4911         pthread_mutex_unlock(&m_parm_lock);
4912         return rc;
4913     }
4914     pthread_mutex_unlock(&m_parm_lock);
4915 
4916     if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() !=true) {
4917         rc = addChannel(QCAMERA_CH_TYPE_ZSL);
4918         if (rc != NO_ERROR) {
4919             ALOGE("%s[%d]: failed!! rc = %d", __func__, __LINE__, rc);
4920             return rc;
4921         }
4922     } else {
4923         bool recordingHint = mParameters.getRecordingHintValue();
4924         if(!isRdiMode() && recordingHint) {
4925             if (!mParameters.is4k2kVideoResolution()) {
4926                rc = addChannel(QCAMERA_CH_TYPE_SNAPSHOT);
4927                if (rc != NO_ERROR) {
4928                    return rc;
4929                }
4930             }
4931             rc = addChannel(QCAMERA_CH_TYPE_VIDEO);
4932             if (rc != NO_ERROR) {
4933                 delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
4934                 ALOGE("%s[%d]:failed!! rc = %d", __func__, __LINE__, rc);
4935                 return rc;
4936             }
4937         }
4938 
4939         rc = addChannel(QCAMERA_CH_TYPE_PREVIEW);
4940         if (!isRdiMode() && (rc != NO_ERROR)) {
4941             if (recordingHint) {
4942                 delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
4943                 delChannel(QCAMERA_CH_TYPE_VIDEO);
4944             }
4945             ALOGE("%s[%d]:failed!! rc = %d", __func__, __LINE__, rc);
4946             return rc;
4947         }
4948 
4949         if (!recordingHint) {
4950             waitDefferedWork(mMetadataJob);
4951         }
4952     }
4953 
4954     return rc;
4955 }
4956 
4957 /*===========================================================================
4958  * FUNCTION   : unpreparePreview
4959  *
4960  * DESCRIPTION: delete channels for preview
4961  *
4962  * PARAMETERS : none
4963  *
4964  * RETURN     : none
4965  *==========================================================================*/
unpreparePreview()4966 void QCamera2HardwareInterface::unpreparePreview()
4967 {
4968     delChannel(QCAMERA_CH_TYPE_ZSL);
4969     delChannel(QCAMERA_CH_TYPE_PREVIEW);
4970     delChannel(QCAMERA_CH_TYPE_VIDEO);
4971     delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
4972 }
4973 
4974 /*===========================================================================
4975  * FUNCTION   : playShutter
4976  *
4977  * DESCRIPTION: send request to play shutter sound
4978  *
4979  * PARAMETERS : none
4980  *
4981  * RETURN     : none
4982  *==========================================================================*/
playShutter()4983 void QCamera2HardwareInterface::playShutter(){
4984      if (mNotifyCb == NULL ||
4985          msgTypeEnabledWithLock(CAMERA_MSG_SHUTTER) == 0){
4986          CDBG("%s: shutter msg not enabled or NULL cb", __func__);
4987          return;
4988      }
4989 
4990      qcamera_callback_argm_t cbArg;
4991      memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
4992      cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK;
4993      cbArg.msg_type = CAMERA_MSG_SHUTTER;
4994      cbArg.ext1 = 0;
4995      cbArg.ext2 = false;
4996      m_cbNotifier.notifyCallback(cbArg);
4997 }
4998 
4999 /*===========================================================================
5000  * FUNCTION   : getChannelByHandle
5001  *
5002  * DESCRIPTION: return a channel by its handle
5003  *
5004  * PARAMETERS :
5005  *   @channelHandle : channel handle
5006  *
5007  * RETURN     : a channel obj if found, NULL if not found
5008  *==========================================================================*/
getChannelByHandle(uint32_t channelHandle)5009 QCameraChannel *QCamera2HardwareInterface::getChannelByHandle(uint32_t channelHandle)
5010 {
5011     for(int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
5012         if (m_channels[i] != NULL &&
5013             m_channels[i]->getMyHandle() == channelHandle) {
5014             return m_channels[i];
5015         }
5016     }
5017 
5018     return NULL;
5019 }
5020 
5021 /*===========================================================================
5022  * FUNCTION   : processFaceDetectionReuslt
5023  *
5024  * DESCRIPTION: process face detection reuslt
5025  *
5026  * PARAMETERS :
5027  *   @fd_data : ptr to face detection result struct
5028  *
5029  * RETURN     : int32_t type of status
5030  *              NO_ERROR  -- success
5031  *              none-zero failure code
5032  *==========================================================================*/
processFaceDetectionResult(cam_face_detection_data_t * fd_data)5033 int32_t QCamera2HardwareInterface::processFaceDetectionResult(cam_face_detection_data_t *fd_data)
5034 {
5035     if (!mParameters.isFaceDetectionEnabled()) {
5036         CDBG_HIGH("%s: FaceDetection not enabled, no ops here", __func__);
5037         return NO_ERROR;
5038     }
5039 
5040     qcamera_face_detect_type_t fd_type = fd_data->fd_type;
5041     if ((NULL == mDataCb) ||
5042         (fd_type == QCAMERA_FD_PREVIEW && !msgTypeEnabled(CAMERA_MSG_PREVIEW_METADATA))
5043 #ifndef VANILLA_HAL
5044         || (fd_type == QCAMERA_FD_SNAPSHOT && !msgTypeEnabled(CAMERA_MSG_META_DATA))
5045 #endif
5046         ) {
5047         CDBG_HIGH("%s: metadata msgtype not enabled, no ops here", __func__);
5048         return NO_ERROR;
5049     }
5050 
5051     cam_dimension_t display_dim;
5052     mParameters.getStreamDimension(CAM_STREAM_TYPE_PREVIEW, display_dim);
5053     if (display_dim.width <= 0 || display_dim.height <= 0) {
5054         ALOGE("%s: Invalid preview width or height (%d x %d)",
5055               __func__, display_dim.width, display_dim.height);
5056         return UNKNOWN_ERROR;
5057     }
5058 
5059     // process face detection result
5060     // need separate face detection in preview or snapshot type
5061     size_t faceResultSize = 0;
5062     size_t data_len = 0;
5063     if(fd_type == QCAMERA_FD_PREVIEW){
5064         //fd for preview frames
5065         faceResultSize = sizeof(camera_frame_metadata_t);
5066         faceResultSize += sizeof(camera_face_t) * MAX_ROI;
5067     }else if(fd_type == QCAMERA_FD_SNAPSHOT){
5068         // fd for snapshot frames
5069         //check if face is detected in this frame
5070         if(fd_data->num_faces_detected > 0){
5071             data_len = sizeof(camera_frame_metadata_t) +
5072                          sizeof(camera_face_t) * fd_data->num_faces_detected;
5073         }else{
5074             //no face
5075             data_len = 0;
5076         }
5077         faceResultSize = 1 *sizeof(int)    //meta data type
5078                        + 1 *sizeof(int)    // meta data len
5079                        + data_len;         //data
5080     }
5081 
5082     camera_memory_t *faceResultBuffer = mGetMemory(-1,
5083                                                    faceResultSize,
5084                                                    1,
5085                                                    mCallbackCookie);
5086     if ( NULL == faceResultBuffer ) {
5087         ALOGE("%s: Not enough memory for face result data",
5088               __func__);
5089         return NO_MEMORY;
5090     }
5091 
5092     unsigned char *pFaceResult = ( unsigned char * ) faceResultBuffer->data;
5093     memset(pFaceResult, 0, faceResultSize);
5094     unsigned char *faceData = NULL;
5095     if(fd_type == QCAMERA_FD_PREVIEW){
5096         faceData = pFaceResult;
5097     }else if(fd_type == QCAMERA_FD_SNAPSHOT){
5098 #ifndef VANILLA_HAL
5099         //need fill meta type and meta data len first
5100         int *data_header = (int* )pFaceResult;
5101         data_header[0] = CAMERA_META_DATA_FD;
5102         data_header[1] = data_len;
5103 
5104         if(data_len <= 0){
5105             //if face is not valid or do not have face, return
5106             qcamera_callback_argm_t cbArg;
5107             memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
5108             cbArg.cb_type = QCAMERA_DATA_CALLBACK;
5109             cbArg.msg_type = CAMERA_MSG_META_DATA;
5110             cbArg.data = faceResultBuffer;
5111             cbArg.user_data = faceResultBuffer;
5112             cbArg.cookie = this;
5113             cbArg.release_cb = releaseCameraMemory;
5114             int32_t rc = m_cbNotifier.notifyCallback(cbArg);
5115             if (rc != NO_ERROR) {
5116                 ALOGE("%s: fail sending notification", __func__);
5117                 faceResultBuffer->release(faceResultBuffer);
5118             }
5119             return rc;
5120         }
5121 #endif
5122         faceData = pFaceResult + 2 *sizeof(int); //skip two int length
5123     }
5124 
5125     camera_frame_metadata_t *roiData = (camera_frame_metadata_t * ) faceData;
5126     camera_face_t *faces = (camera_face_t *) ( faceData + sizeof(camera_frame_metadata_t) );
5127 
5128     roiData->number_of_faces = fd_data->num_faces_detected;
5129     roiData->faces = faces;
5130     if (roiData->number_of_faces > 0) {
5131         for (int i = 0; i < roiData->number_of_faces; i++) {
5132             faces[i].id = fd_data->faces[i].face_id;
5133             faces[i].score = fd_data->faces[i].score;
5134 
5135             // left
5136             faces[i].rect[0] =
5137                 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].face_boundary.left, display_dim.width, 2000, -1000);
5138 
5139             // top
5140             faces[i].rect[1] =
5141                 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].face_boundary.top, display_dim.height, 2000, -1000);
5142 
5143             // right
5144             faces[i].rect[2] = faces[i].rect[0] +
5145                 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].face_boundary.width, display_dim.width, 2000, 0);
5146 
5147              // bottom
5148             faces[i].rect[3] = faces[i].rect[1] +
5149                 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].face_boundary.height, display_dim.height, 2000, 0);
5150 
5151             // Center of left eye
5152             faces[i].left_eye[0] =
5153                 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].left_eye_center.x, display_dim.width, 2000, -1000);
5154 
5155             faces[i].left_eye[1] =
5156                 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].left_eye_center.y, display_dim.height, 2000, -1000);
5157 
5158             // Center of right eye
5159             faces[i].right_eye[0] =
5160                 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].right_eye_center.x, display_dim.width, 2000, -1000);
5161 
5162             faces[i].right_eye[1] =
5163                 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].right_eye_center.y, display_dim.height, 2000, -1000);
5164 
5165             // Center of mouth
5166             faces[i].mouth[0] =
5167                 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].mouth_center.x, display_dim.width, 2000, -1000);
5168 
5169             faces[i].mouth[1] =
5170                 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].mouth_center.y, display_dim.height, 2000, -1000);
5171 
5172 #ifndef VANILLA_HAL
5173             faces[i].smile_degree = fd_data->faces[i].smile_degree;
5174             faces[i].smile_score = fd_data->faces[i].smile_confidence;
5175             faces[i].blink_detected = fd_data->faces[i].blink_detected;
5176             faces[i].face_recognised = fd_data->faces[i].face_recognised;
5177             faces[i].gaze_angle = fd_data->faces[i].gaze_angle;
5178 
5179             // upscale by 2 to recover from demaen downscaling
5180             faces[i].updown_dir = fd_data->faces[i].updown_dir * 2;
5181             faces[i].leftright_dir = fd_data->faces[i].leftright_dir * 2;
5182             faces[i].roll_dir = fd_data->faces[i].roll_dir * 2;
5183 
5184             faces[i].leye_blink = fd_data->faces[i].left_blink;
5185             faces[i].reye_blink = fd_data->faces[i].right_blink;
5186             faces[i].left_right_gaze = fd_data->faces[i].left_right_gaze;
5187             faces[i].top_bottom_gaze = fd_data->faces[i].top_bottom_gaze;
5188 #endif
5189 
5190         }
5191     }
5192 
5193     qcamera_callback_argm_t cbArg;
5194     memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
5195     cbArg.cb_type = QCAMERA_DATA_CALLBACK;
5196     if(fd_type == QCAMERA_FD_PREVIEW){
5197         cbArg.msg_type = CAMERA_MSG_PREVIEW_METADATA;
5198     }
5199 #ifndef VANILLA_HAL
5200     else if(fd_type == QCAMERA_FD_SNAPSHOT){
5201         cbArg.msg_type = CAMERA_MSG_META_DATA;
5202     }
5203 #endif
5204     cbArg.data = faceResultBuffer;
5205     cbArg.metadata = roiData;
5206     cbArg.user_data = faceResultBuffer;
5207     cbArg.cookie = this;
5208     cbArg.release_cb = releaseCameraMemory;
5209     int32_t rc = m_cbNotifier.notifyCallback(cbArg);
5210     if (rc != NO_ERROR) {
5211         ALOGE("%s: fail sending notification", __func__);
5212         faceResultBuffer->release(faceResultBuffer);
5213     }
5214 
5215     return rc;
5216 }
5217 
5218 /*===========================================================================
5219  * FUNCTION   : releaseCameraMemory
5220  *
5221  * DESCRIPTION: releases camera memory objects
5222  *
5223  * PARAMETERS :
5224  *   @data    : buffer to be released
5225  *   @cookie  : context data
5226  *   @cbStatus: callback status
5227  *
5228  * RETURN     : None
5229  *==========================================================================*/
releaseCameraMemory(void * data,void *,int32_t)5230 void QCamera2HardwareInterface::releaseCameraMemory(void *data,
5231                                                     void */*cookie*/,
5232                                                     int32_t /*cbStatus*/)
5233 {
5234     camera_memory_t *mem = ( camera_memory_t * ) data;
5235     if ( NULL != mem ) {
5236         mem->release(mem);
5237     }
5238 }
5239 
5240 /*===========================================================================
5241  * FUNCTION   : returnStreamBuffer
5242  *
5243  * DESCRIPTION: returns back a stream buffer
5244  *
5245  * PARAMETERS :
5246  *   @data    : buffer to be released
5247  *   @cookie  : context data
5248  *   @cbStatus: callback status
5249  *
5250  * RETURN     : None
5251  *==========================================================================*/
returnStreamBuffer(void * data,void * cookie,int32_t)5252 void QCamera2HardwareInterface::returnStreamBuffer(void *data,
5253                                                    void *cookie,
5254                                                    int32_t /*cbStatus*/)
5255 {
5256     QCameraStream *stream = ( QCameraStream * ) cookie;
5257     int idx = ( int ) data;
5258     if ( ( NULL != stream )) {
5259         stream->bufDone(idx);
5260     }
5261 }
5262 
5263 /*===========================================================================
5264  * FUNCTION   : processHistogramStats
5265  *
5266  * DESCRIPTION: process histogram stats
5267  *
5268  * PARAMETERS :
5269  *   @hist_data : ptr to histogram stats struct
5270  *
5271  * RETURN     : int32_t type of status
5272  *              NO_ERROR  -- success
5273  *              none-zero failure code
5274  *==========================================================================*/
processHistogramStats(cam_hist_stats_t & stats_data)5275 int32_t QCamera2HardwareInterface::processHistogramStats(cam_hist_stats_t &stats_data)
5276 {
5277 #ifndef VANILLA_HAL
5278     if (!mParameters.isHistogramEnabled()) {
5279         CDBG_HIGH("%s: Histogram not enabled, no ops here", __func__);
5280         return NO_ERROR;
5281     }
5282 
5283     camera_memory_t *histBuffer = mGetMemory(-1,
5284                                              sizeof(cam_histogram_data_t),
5285                                              1,
5286                                              mCallbackCookie);
5287     if ( NULL == histBuffer ) {
5288         ALOGE("%s: Not enough memory for histogram data",
5289               __func__);
5290         return NO_MEMORY;
5291     }
5292 
5293     cam_histogram_data_t *pHistData = (cam_histogram_data_t *)histBuffer->data;
5294     if (pHistData == NULL) {
5295         ALOGE("%s: memory data ptr is NULL", __func__);
5296         return UNKNOWN_ERROR;
5297     }
5298 
5299     switch (stats_data.type) {
5300     case CAM_HISTOGRAM_TYPE_BAYER:
5301         *pHistData = stats_data.bayer_stats.gb_stats;
5302         break;
5303     case CAM_HISTOGRAM_TYPE_YUV:
5304         *pHistData = stats_data.yuv_stats;
5305         break;
5306     }
5307 
5308     qcamera_callback_argm_t cbArg;
5309     memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
5310     cbArg.cb_type = QCAMERA_DATA_CALLBACK;
5311     cbArg.msg_type = CAMERA_MSG_STATS_DATA;
5312     cbArg.data = histBuffer;
5313     cbArg.user_data = histBuffer;
5314     cbArg.cookie = this;
5315     cbArg.release_cb = releaseCameraMemory;
5316     int32_t rc = m_cbNotifier.notifyCallback(cbArg);
5317     if (rc != NO_ERROR) {
5318         ALOGE("%s: fail sending notification", __func__);
5319         histBuffer->release(histBuffer);
5320     }
5321 #endif
5322     return NO_ERROR;
5323 }
5324 
5325 /*===========================================================================
5326  * FUNCTION   : calcThermalLevel
5327  *
5328  * DESCRIPTION: Calculates the target fps range depending on
5329  *              the thermal level.
5330  *
5331  * PARAMETERS :
5332  *   @level    : received thermal level
5333  *   @minFPS   : minimum configured fps range
5334  *   @maxFPS   : maximum configured fps range
5335  *   @adjustedRange : target fps range
5336  *   @skipPattern : target skip pattern
5337  *
5338  * RETURN     : int32_t type of status
5339  *              NO_ERROR  -- success
5340  *              none-zero failure code
5341  *==========================================================================*/
calcThermalLevel(qcamera_thermal_level_enum_t level,const int minFPS,const int maxFPS,cam_fps_range_t & adjustedRange,enum msm_vfe_frame_skip_pattern & skipPattern)5342 int QCamera2HardwareInterface::calcThermalLevel(
5343             qcamera_thermal_level_enum_t level,
5344             const int minFPS,
5345             const int maxFPS,
5346             cam_fps_range_t &adjustedRange,
5347             enum msm_vfe_frame_skip_pattern &skipPattern)
5348 {
5349     // Initialize video fps to preview fps
5350     int minVideoFps = minFPS, maxVideoFps = maxFPS;
5351     cam_fps_range_t videoFps;
5352     // If HFR mode, update video fps accordingly
5353     if(isHFRMode()) {
5354         mParameters.getHfrFps(videoFps);
5355         minVideoFps = videoFps.video_min_fps;
5356         maxVideoFps = videoFps.video_max_fps;
5357     }
5358 
5359     CDBG_HIGH("%s: level: %d, preview minfps %d, preview maxfpS %d"
5360           "video minfps %d, video maxfpS %d",
5361           __func__, level, minFPS, maxFPS, minVideoFps, maxVideoFps);
5362 
5363     switch(level) {
5364     case QCAMERA_THERMAL_NO_ADJUSTMENT:
5365         {
5366             adjustedRange.min_fps = minFPS / 1000.0f;
5367             adjustedRange.max_fps = maxFPS / 1000.0f;
5368             adjustedRange.video_min_fps = minVideoFps / 1000.0f;
5369             adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
5370             skipPattern = NO_SKIP;
5371         }
5372         break;
5373     case QCAMERA_THERMAL_SLIGHT_ADJUSTMENT:
5374         {
5375             adjustedRange.min_fps = minFPS / 1000.0f;
5376             adjustedRange.max_fps = maxFPS / 1000.0f;
5377             adjustedRange.min_fps -= 0.1f * adjustedRange.min_fps;
5378             adjustedRange.max_fps -= 0.1f * adjustedRange.max_fps;
5379             adjustedRange.video_min_fps = minVideoFps / 1000.0f;
5380             adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
5381             adjustedRange.video_min_fps -= 0.1f * adjustedRange.video_min_fps;
5382             adjustedRange.video_max_fps -= 0.1f * adjustedRange.video_max_fps;
5383             if ( adjustedRange.min_fps < 1 ) {
5384                 adjustedRange.min_fps = 1;
5385             }
5386             if ( adjustedRange.max_fps < 1 ) {
5387                 adjustedRange.max_fps = 1;
5388             }
5389             if ( adjustedRange.video_min_fps < 1 ) {
5390                 adjustedRange.video_min_fps = 1;
5391             }
5392             if ( adjustedRange.video_max_fps < 1 ) {
5393                 adjustedRange.video_max_fps = 1;
5394             }
5395             skipPattern = EVERY_2FRAME;
5396         }
5397         break;
5398     case QCAMERA_THERMAL_BIG_ADJUSTMENT:
5399         {
5400             adjustedRange.min_fps = minFPS / 1000.0f;
5401             adjustedRange.max_fps = maxFPS / 1000.0f;
5402             adjustedRange.min_fps -= 0.2f * adjustedRange.min_fps;
5403             adjustedRange.max_fps -= 0.2f * adjustedRange.max_fps;
5404             adjustedRange.video_min_fps = minVideoFps / 1000.0f;
5405             adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
5406             adjustedRange.video_min_fps -= 0.2f * adjustedRange.video_min_fps;
5407             adjustedRange.video_max_fps -= 0.2f * adjustedRange.video_max_fps;
5408             if ( adjustedRange.min_fps < 1 ) {
5409                 adjustedRange.min_fps = 1;
5410             }
5411             if ( adjustedRange.max_fps < 1 ) {
5412                 adjustedRange.max_fps = 1;
5413             }
5414             if ( adjustedRange.video_min_fps < 1 ) {
5415                 adjustedRange.video_min_fps = 1;
5416             }
5417             if ( adjustedRange.video_max_fps < 1 ) {
5418                 adjustedRange.video_max_fps = 1;
5419             }
5420             skipPattern = EVERY_4FRAME;
5421         }
5422         break;
5423     case QCAMERA_THERMAL_SHUTDOWN:
5424         {
5425             // Stop Preview?
5426             // Set lowest min FPS for now
5427             adjustedRange.min_fps = minFPS/1000.0f;
5428             adjustedRange.max_fps = minFPS/1000.0f;
5429             for ( int i = 0 ; i < gCamCaps[mCameraId]->fps_ranges_tbl_cnt ; i++ ) {
5430                 if ( gCamCaps[mCameraId]->fps_ranges_tbl[i].min_fps < adjustedRange.min_fps ) {
5431                     adjustedRange.min_fps = gCamCaps[mCameraId]->fps_ranges_tbl[i].min_fps;
5432                     adjustedRange.max_fps = adjustedRange.min_fps;
5433                 }
5434             }
5435             skipPattern = MAX_SKIP;
5436             adjustedRange.video_min_fps = adjustedRange.min_fps;
5437             adjustedRange.video_max_fps = adjustedRange.max_fps;
5438         }
5439         break;
5440     default:
5441         {
5442             ALOGE("%s: Invalid thermal level %d", __func__, level);
5443             return BAD_VALUE;
5444         }
5445         break;
5446     }
5447     CDBG_HIGH("%s: Thermal level %d, FPS [%3.2f,%3.2f, %3.2f,%3.2f], frameskip %d",
5448           __func__, level, adjustedRange.min_fps, adjustedRange.max_fps,
5449           adjustedRange.video_min_fps, adjustedRange.video_max_fps, skipPattern);
5450 
5451     return NO_ERROR;
5452 }
5453 
5454 /*===========================================================================
5455  * FUNCTION   : recalcFPSRange
5456  *
5457  * DESCRIPTION: adjust the configured fps range regarding
5458  *              the last thermal level.
5459  *
5460  * PARAMETERS :
5461  *   @minFPS   : minimum configured fps range
5462  *   @maxFPS   : maximum configured fps range
5463  *
5464  * RETURN     : int32_t type of status
5465  *              NO_ERROR  -- success
5466  *              none-zero failure code
5467  *==========================================================================*/
recalcFPSRange(int & minFPS,int & maxFPS,int & vidMinFps,int & vidMaxFps)5468 int QCamera2HardwareInterface::recalcFPSRange(int &minFPS, int &maxFPS,
5469         int &vidMinFps, int &vidMaxFps)
5470 {
5471     cam_fps_range_t adjustedRange;
5472     enum msm_vfe_frame_skip_pattern skipPattern;
5473     calcThermalLevel(mThermalLevel,
5474                      minFPS,
5475                      maxFPS,
5476                      adjustedRange,
5477                      skipPattern);
5478     minFPS = adjustedRange.min_fps;
5479     maxFPS = adjustedRange.max_fps;
5480     vidMinFps = adjustedRange.video_min_fps;
5481     vidMaxFps = adjustedRange.video_max_fps;
5482 
5483     return NO_ERROR;
5484 }
5485 
5486 /*===========================================================================
5487  * FUNCTION   : updateThermalLevel
5488  *
5489  * DESCRIPTION: update thermal level depending on thermal events
5490  *
5491  * PARAMETERS :
5492  *   @level   : thermal level
5493  *
5494  * RETURN     : int32_t type of status
5495  *              NO_ERROR  -- success
5496  *              none-zero failure code
5497  *==========================================================================*/
updateThermalLevel(qcamera_thermal_level_enum_t level)5498 int QCamera2HardwareInterface::updateThermalLevel(
5499             qcamera_thermal_level_enum_t level)
5500 {
5501     int ret = NO_ERROR;
5502     cam_fps_range_t adjustedRange;
5503     int minFPS, maxFPS;
5504     enum msm_vfe_frame_skip_pattern skipPattern;
5505 
5506     pthread_mutex_lock(&m_parm_lock);
5507 
5508     if (!mCameraOpened) {
5509         CDBG_HIGH("%s: Camera is not opened, no need to update camera parameters", __func__);
5510         pthread_mutex_unlock(&m_parm_lock);
5511         return NO_ERROR;
5512     }
5513 
5514     mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
5515     qcamera_thermal_mode thermalMode = mParameters.getThermalMode();
5516     calcThermalLevel(level, minFPS, maxFPS, adjustedRange, skipPattern);
5517     mThermalLevel = level;
5518 
5519     if (thermalMode == QCAMERA_THERMAL_ADJUST_FPS)
5520         ret = mParameters.adjustPreviewFpsRange(&adjustedRange);
5521     else if (thermalMode == QCAMERA_THERMAL_ADJUST_FRAMESKIP)
5522         ret = mParameters.setFrameSkip(skipPattern);
5523     else
5524         ALOGE("%s: Incorrect thermal mode %d", __func__, thermalMode);
5525 
5526     pthread_mutex_unlock(&m_parm_lock);
5527 
5528     return ret;
5529 
5530 }
5531 
5532 /*===========================================================================
5533  * FUNCTION   : updateParameters
5534  *
5535  * DESCRIPTION: update parameters
5536  *
5537  * PARAMETERS :
5538  *   @parms       : input parameters string
5539  *   @needRestart : output, flag to indicate if preview restart is needed
5540  *
5541  * RETURN     : int32_t type of status
5542  *              NO_ERROR  -- success
5543  *              none-zero failure code
5544  *==========================================================================*/
updateParameters(const char * parms,bool & needRestart)5545 int QCamera2HardwareInterface::updateParameters(const char *parms, bool &needRestart)
5546 {
5547     int rc = NO_ERROR;
5548     pthread_mutex_lock(&m_parm_lock);
5549     String8 str = String8(parms);
5550     QCameraParameters param(str);
5551     rc =  mParameters.updateParameters(param, needRestart);
5552 
5553     // update stream based parameter settings
5554     for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
5555         if (m_channels[i] != NULL) {
5556             m_channels[i]->UpdateStreamBasedParameters(mParameters);
5557         }
5558     }
5559     pthread_mutex_unlock(&m_parm_lock);
5560 
5561     return rc;
5562 }
5563 
5564 /*===========================================================================
5565  * FUNCTION   : commitParameterChanges
5566  *
5567  * DESCRIPTION: commit parameter changes to the backend to take effect
5568  *
5569  * PARAMETERS : none
5570  *
5571  * RETURN     : int32_t type of status
5572  *              NO_ERROR  -- success
5573  *              none-zero failure code
5574  * NOTE       : This function must be called after updateParameters.
5575  *              Otherwise, no change will be passed to backend to take effect.
5576  *==========================================================================*/
commitParameterChanges()5577 int QCamera2HardwareInterface::commitParameterChanges()
5578 {
5579     int rc = NO_ERROR;
5580     pthread_mutex_lock(&m_parm_lock);
5581     rc = mParameters.commitParameters();
5582     if (rc == NO_ERROR) {
5583         // update number of snapshot based on committed parameters setting
5584         rc = mParameters.setNumOfSnapshot();
5585     }
5586     pthread_mutex_unlock(&m_parm_lock);
5587     return rc;
5588 }
5589 
5590 /*===========================================================================
5591  * FUNCTION   : needDebugFps
5592  *
5593  * DESCRIPTION: if fps log info need to be printed out
5594  *
5595  * PARAMETERS : none
5596  *
5597  * RETURN     : true: need print out fps log
5598  *              false: no need to print out fps log
5599  *==========================================================================*/
needDebugFps()5600 bool QCamera2HardwareInterface::needDebugFps()
5601 {
5602     bool needFps = false;
5603     pthread_mutex_lock(&m_parm_lock);
5604     needFps = mParameters.isFpsDebugEnabled();
5605     pthread_mutex_unlock(&m_parm_lock);
5606     return needFps;
5607 }
5608 
5609 /*===========================================================================
5610  * FUNCTION   : isCACEnabled
5611  *
5612  * DESCRIPTION: if CAC is enabled
5613  *
5614  * PARAMETERS : none
5615  *
5616  * RETURN     : true: needed
5617  *              false: no need
5618  *==========================================================================*/
isCACEnabled()5619 bool QCamera2HardwareInterface::isCACEnabled()
5620 {
5621     char prop[PROPERTY_VALUE_MAX];
5622     memset(prop, 0, sizeof(prop));
5623     property_get("persist.camera.feature.cac", prop, "0");
5624     int enableCAC = atoi(prop);
5625     return enableCAC == 1;
5626 }
5627 
5628 /*===========================================================================
5629  * FUNCTION   : is4k2kResolution
5630  *
5631  * DESCRIPTION: if resolution is 4k x 2k or true 4k x 2k
5632  *
5633  * PARAMETERS : none
5634  *
5635  * RETURN     : true: needed
5636  *              false: no need
5637  *==========================================================================*/
is4k2kResolution(cam_dimension_t * resolution)5638 bool QCamera2HardwareInterface::is4k2kResolution(cam_dimension_t* resolution)
5639 {
5640    bool enabled = false;
5641    if ((resolution->width == 4096 && resolution->height == 2160) ||
5642        (resolution->width == 3840 && resolution->height == 2160) ) {
5643       enabled = true;
5644    }
5645    return enabled;
5646 }
5647 
5648 
5649 /*===========================================================================
5650  * FUNCTION   : isAFRunning
5651  *
5652  * DESCRIPTION: if AF is in progress while in Auto/Macro focus modes
5653  *
5654  * PARAMETERS : none
5655  *
5656  * RETURN     : true: AF in progress
5657  *              false: AF not in progress
5658  *==========================================================================*/
isAFRunning()5659 bool QCamera2HardwareInterface::isAFRunning()
5660 {
5661     bool isAFInProgress = (m_currentFocusState == CAM_AF_SCANNING &&
5662             (mParameters.getFocusMode() == CAM_FOCUS_MODE_AUTO ||
5663             mParameters.getFocusMode() == CAM_FOCUS_MODE_MACRO));
5664 
5665     return isAFInProgress;
5666 }
5667 
5668 /*===========================================================================
5669  * FUNCTION   : isPreviewRestartEnabled
5670  *
5671  * DESCRIPTION: Check whether preview should be restarted automatically
5672  *              during image capture.
5673  *
5674  * PARAMETERS : none
5675  *
5676  * RETURN     : true: needed
5677  *              false: no need
5678  *==========================================================================*/
isPreviewRestartEnabled()5679 bool QCamera2HardwareInterface::isPreviewRestartEnabled()
5680 {
5681     char prop[PROPERTY_VALUE_MAX];
5682     memset(prop, 0, sizeof(prop));
5683     property_get("persist.camera.feature.restart", prop, "0");
5684     int earlyRestart = atoi(prop);
5685     return earlyRestart == 1;
5686 }
5687 
5688 /*===========================================================================
5689  * FUNCTION   : needReprocess
5690  *
5691  * DESCRIPTION: if reprocess is needed
5692  *
5693  * PARAMETERS : none
5694  *
5695  * RETURN     : true: needed
5696  *              false: no need
5697  *==========================================================================*/
needReprocess()5698 bool QCamera2HardwareInterface::needReprocess()
5699 {
5700     pthread_mutex_lock(&m_parm_lock);
5701     if (!mParameters.isJpegPictureFormat() &&
5702         !mParameters.isNV21PictureFormat()) {
5703         // RAW image, no need to reprocess
5704         pthread_mutex_unlock(&m_parm_lock);
5705         return false;
5706     }
5707 
5708     if (mParameters.isHDREnabled()) {
5709         CDBG_HIGH("%s: need do reprocess for HDR", __func__);
5710         pthread_mutex_unlock(&m_parm_lock);
5711         return true;
5712     }
5713 
5714     if ((gCamCaps[mCameraId]->qcom_supported_feature_mask & CAM_QCOM_FEATURE_ROTATION) > 0 &&
5715             (getJpegRotation() > 0) &&  (mParameters.getRecordingHintValue() == false)) {
5716             // current rotation is not zero, and pp has the capability to process rotation
5717             CDBG_HIGH("%s: need to do reprocess for rotation=%d", __func__, getJpegRotation());
5718             pthread_mutex_unlock(&m_parm_lock);
5719             return true;
5720     }
5721 
5722     if (isZSLMode()) {
5723         if (((gCamCaps[mCameraId]->min_required_pp_mask > 0) ||
5724              mParameters.isWNREnabled() || isCACEnabled())) {
5725             // TODO: add for ZSL HDR later
5726             CDBG_HIGH("%s: need do reprocess for ZSL WNR or min PP reprocess", __func__);
5727             pthread_mutex_unlock(&m_parm_lock);
5728             return true;
5729         }
5730 
5731         int snapshot_flipMode =
5732             mParameters.getFlipMode(CAM_STREAM_TYPE_SNAPSHOT);
5733         if (snapshot_flipMode > 0) {
5734             CDBG_HIGH("%s: Need do flip for snapshot in ZSL mode", __func__);
5735             pthread_mutex_unlock(&m_parm_lock);
5736             return true;
5737         }
5738     }
5739 
5740     if ((gCamCaps[mCameraId]->qcom_supported_feature_mask & CAM_QCOM_FEATURE_SCALE) > 0 &&
5741         mParameters.m_reprocScaleParam.isScaleEnabled() &&
5742         mParameters.m_reprocScaleParam.isUnderScaling()) {
5743         // Reproc Scale is enaled and also need Scaling to current Snapshot
5744         CDBG_HIGH("%s: need do reprocess for scale", __func__);
5745         pthread_mutex_unlock(&m_parm_lock);
5746         return true;
5747     }
5748 
5749     if (mParameters.isUbiFocusEnabled() |
5750         mParameters.isChromaFlashEnabled() |
5751         mParameters.isHDREnabled() |
5752         mParameters.isOptiZoomEnabled()) {
5753         CDBG_HIGH("%s: need reprocess for |UbiFocus=%d|ChramaFlash=%d|OptiZoom=%d|",
5754                                          __func__,
5755                                          mParameters.isUbiFocusEnabled(),
5756                                          mParameters.isChromaFlashEnabled(),
5757                                          mParameters.isOptiZoomEnabled());
5758         pthread_mutex_unlock(&m_parm_lock);
5759         return true;
5760     }
5761 
5762     pthread_mutex_unlock(&m_parm_lock);
5763     return false;
5764 }
5765 
5766 /*===========================================================================
5767  * FUNCTION   : needRotationReprocess
5768  *
5769  * DESCRIPTION: if rotation needs to be done by reprocess in pp
5770  *
5771  * PARAMETERS : none
5772  *
5773  * RETURN     : true: needed
5774  *              false: no need
5775  *==========================================================================*/
needRotationReprocess()5776 bool QCamera2HardwareInterface::needRotationReprocess()
5777 {
5778     pthread_mutex_lock(&m_parm_lock);
5779     if (!mParameters.isJpegPictureFormat() &&
5780         !mParameters.isNV21PictureFormat()) {
5781         // RAW image, no need to reprocess
5782         pthread_mutex_unlock(&m_parm_lock);
5783         return false;
5784     }
5785 
5786         if ((gCamCaps[mCameraId]->qcom_supported_feature_mask & CAM_QCOM_FEATURE_ROTATION) > 0 &&
5787             (getJpegRotation() > 0) && (mParameters.getRecordingHintValue() == false)) {
5788             // current rotation is not zero, and pp has the capability to process rotation
5789             CDBG_HIGH("%s: need to do reprocess for rotation=%d", __func__, getJpegRotation());
5790             pthread_mutex_unlock(&m_parm_lock);
5791             return true;
5792         }
5793 
5794     pthread_mutex_unlock(&m_parm_lock);
5795     return false;
5796 }
5797 
5798 /*===========================================================================
5799  * FUNCTION   : needScaleReprocess
5800  *
5801  * DESCRIPTION: if scale needs to be done by reprocess in pp
5802  *
5803  * PARAMETERS : none
5804  *
5805  * RETURN     : true: needed
5806  *              false: no need
5807  *==========================================================================*/
needScaleReprocess()5808 bool QCamera2HardwareInterface::needScaleReprocess()
5809 {
5810     pthread_mutex_lock(&m_parm_lock);
5811     if (!mParameters.isJpegPictureFormat() &&
5812         !mParameters.isNV21PictureFormat()) {
5813         // RAW image, no need to reprocess
5814         pthread_mutex_unlock(&m_parm_lock);
5815         return false;
5816     }
5817 
5818     if ((gCamCaps[mCameraId]->qcom_supported_feature_mask & CAM_QCOM_FEATURE_SCALE) > 0 &&
5819         mParameters.m_reprocScaleParam.isScaleEnabled() &&
5820         mParameters.m_reprocScaleParam.isUnderScaling()) {
5821         // Reproc Scale is enaled and also need Scaling to current Snapshot
5822         CDBG_HIGH("%s: need do reprocess for scale", __func__);
5823         pthread_mutex_unlock(&m_parm_lock);
5824         return true;
5825     }
5826 
5827     pthread_mutex_unlock(&m_parm_lock);
5828     return false;
5829 }
5830 
5831 /*===========================================================================
5832  * FUNCTION   : getThumbnailSize
5833  *
5834  * DESCRIPTION: get user set thumbnail size
5835  *
5836  * PARAMETERS :
5837  *   @dim     : output of thumbnail dimension
5838  *
5839  * RETURN     : none
5840  *==========================================================================*/
getThumbnailSize(cam_dimension_t & dim)5841 void QCamera2HardwareInterface::getThumbnailSize(cam_dimension_t &dim)
5842 {
5843     pthread_mutex_lock(&m_parm_lock);
5844     mParameters.getThumbnailSize(&dim.width, &dim.height);
5845     pthread_mutex_unlock(&m_parm_lock);
5846 }
5847 
5848 /*===========================================================================
5849  * FUNCTION   : getJpegQuality
5850  *
5851  * DESCRIPTION: get user set jpeg quality
5852  *
5853  * PARAMETERS : none
5854  *
5855  * RETURN     : jpeg quality setting
5856  *==========================================================================*/
getJpegQuality()5857 int QCamera2HardwareInterface::getJpegQuality()
5858 {
5859     int quality = 0;
5860     pthread_mutex_lock(&m_parm_lock);
5861     quality =  mParameters.getJpegQuality();
5862     pthread_mutex_unlock(&m_parm_lock);
5863     return quality;
5864 }
5865 
5866 /*===========================================================================
5867  * FUNCTION   : getJpegRotation
5868  *
5869  * DESCRIPTION: get rotation information to be passed into jpeg encoding
5870  *
5871  * PARAMETERS : none
5872  *
5873  * RETURN     : rotation information
5874  *==========================================================================*/
getJpegRotation()5875 int QCamera2HardwareInterface::getJpegRotation() {
5876     return mCaptureRotation;
5877 }
5878 
5879 /*===========================================================================
5880  * FUNCTION   : getOrientation
5881  *
5882  * DESCRIPTION: get rotation information from camera parameters
5883  *
5884  * PARAMETERS : none
5885  *
5886  * RETURN     : rotation information
5887  *==========================================================================*/
getOrientation()5888 void QCamera2HardwareInterface::getOrientation() {
5889     pthread_mutex_lock(&m_parm_lock);
5890     mCaptureRotation = mParameters.getJpegRotation();
5891     pthread_mutex_unlock(&m_parm_lock);
5892 }
5893 
5894 /*===========================================================================
5895  * FUNCTION   : getExifData
5896  *
5897  * DESCRIPTION: get exif data to be passed into jpeg encoding
5898  *
5899  * PARAMETERS : none
5900  *
5901  * RETURN     : exif data from user setting and GPS
5902  *==========================================================================*/
getExifData()5903 QCameraExif *QCamera2HardwareInterface::getExifData()
5904 {
5905     QCameraExif *exif = new QCameraExif();
5906     if (exif == NULL) {
5907         ALOGE("%s: No memory for QCameraExif", __func__);
5908         return NULL;
5909     }
5910 
5911     int32_t rc = NO_ERROR;
5912     uint32_t count = 0;
5913 
5914     pthread_mutex_lock(&m_parm_lock);
5915 
5916     // add exif entries
5917     char dateTime[20];
5918     memset(dateTime, 0, sizeof(dateTime));
5919     count = 20;
5920     rc = mParameters.getExifDateTime(dateTime, count);
5921     if(rc == NO_ERROR) {
5922         exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL,
5923                        EXIF_ASCII,
5924                        count,
5925                        (void *)dateTime);
5926     } else {
5927         ALOGE("%s: getExifDateTime failed", __func__);
5928     }
5929 
5930     rat_t focalLength;
5931     rc = mParameters.getExifFocalLength(&focalLength);
5932     if (rc == NO_ERROR) {
5933         exif->addEntry(EXIFTAGID_FOCAL_LENGTH,
5934                        EXIF_RATIONAL,
5935                        1,
5936                        (void *)&(focalLength));
5937     } else {
5938         ALOGE("%s: getExifFocalLength failed", __func__);
5939     }
5940 
5941     uint16_t isoSpeed = mParameters.getExifIsoSpeed();
5942     exif->addEntry(EXIFTAGID_ISO_SPEED_RATING,
5943                    EXIF_SHORT,
5944                    1,
5945                    (void *)&(isoSpeed));
5946 
5947     char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE];
5948     count = 0;
5949     rc = mParameters.getExifGpsProcessingMethod(gpsProcessingMethod, count);
5950     if(rc == NO_ERROR) {
5951         exif->addEntry(EXIFTAGID_GPS_PROCESSINGMETHOD,
5952                        EXIF_ASCII,
5953                        count,
5954                        (void *)gpsProcessingMethod);
5955     } else {
5956         ALOGE("%s: getExifGpsProcessingMethod failed", __func__);
5957     }
5958 
5959     rat_t latitude[3];
5960     char latRef[2];
5961     rc = mParameters.getExifLatitude(latitude, latRef);
5962     if(rc == NO_ERROR) {
5963         exif->addEntry(EXIFTAGID_GPS_LATITUDE,
5964                        EXIF_RATIONAL,
5965                        3,
5966                        (void *)latitude);
5967         exif->addEntry(EXIFTAGID_GPS_LATITUDE_REF,
5968                        EXIF_ASCII,
5969                        2,
5970                        (void *)latRef);
5971     } else {
5972         ALOGE("%s: getExifLatitude failed", __func__);
5973     }
5974 
5975     rat_t longitude[3];
5976     char lonRef[2];
5977     rc = mParameters.getExifLongitude(longitude, lonRef);
5978     if(rc == NO_ERROR) {
5979         exif->addEntry(EXIFTAGID_GPS_LONGITUDE,
5980                        EXIF_RATIONAL,
5981                        3,
5982                        (void *)longitude);
5983 
5984         exif->addEntry(EXIFTAGID_GPS_LONGITUDE_REF,
5985                        EXIF_ASCII,
5986                        2,
5987                        (void *)lonRef);
5988     } else {
5989         ALOGE("%s: getExifLongitude failed", __func__);
5990     }
5991 
5992     rat_t altitude;
5993     char altRef;
5994     rc = mParameters.getExifAltitude(&altitude, &altRef);
5995     if(rc == NO_ERROR) {
5996         exif->addEntry(EXIFTAGID_GPS_ALTITUDE,
5997                        EXIF_RATIONAL,
5998                        1,
5999                        (void *)&(altitude));
6000 
6001         exif->addEntry(EXIFTAGID_GPS_ALTITUDE_REF,
6002                        EXIF_BYTE,
6003                        1,
6004                        (void *)&altRef);
6005     } else {
6006         ALOGE("%s: getExifAltitude failed", __func__);
6007     }
6008 
6009     char gpsDateStamp[20];
6010     rat_t gpsTimeStamp[3];
6011     rc = mParameters.getExifGpsDateTimeStamp(gpsDateStamp, 20, gpsTimeStamp);
6012     if(rc == NO_ERROR) {
6013         exif->addEntry(EXIFTAGID_GPS_DATESTAMP,
6014                        EXIF_ASCII,
6015                        strlen(gpsDateStamp) + 1,
6016                        (void *)gpsDateStamp);
6017 
6018         exif->addEntry(EXIFTAGID_GPS_TIMESTAMP,
6019                        EXIF_RATIONAL,
6020                        3,
6021                        (void *)gpsTimeStamp);
6022     } else {
6023         ALOGE("%s: getExifGpsDataTimeStamp failed", __func__);
6024     }
6025 
6026     char value[PROPERTY_VALUE_MAX];
6027     if (property_get("ro.product.manufacturer", value, "QCOM-AA") > 0) {
6028         exif->addEntry(EXIFTAGID_MAKE,
6029                        EXIF_ASCII,
6030                        strlen(value) + 1,
6031                        (void *)value);
6032     } else {
6033         ALOGE("%s: getExifMaker failed", __func__);
6034     }
6035 
6036     if (property_get("ro.product.model", value, "QCAM-AA") > 0) {
6037         exif->addEntry(EXIFTAGID_MODEL,
6038                        EXIF_ASCII,
6039                        strlen(value) + 1,
6040                        (void *)value);
6041     } else {
6042         ALOGE("%s: getExifModel failed", __func__);
6043     }
6044 
6045     pthread_mutex_unlock(&m_parm_lock);
6046     return exif;
6047 }
6048 
6049 /*===========================================================================
6050  * FUNCTION   : setHistogram
6051  *
6052  * DESCRIPTION: set if histogram should be enabled
6053  *
6054  * PARAMETERS :
6055  *   @histogram_en : bool flag if histogram should be enabled
6056  *
6057  * RETURN     : int32_t type of status
6058  *              NO_ERROR  -- success
6059  *              none-zero failure code
6060  *==========================================================================*/
setHistogram(bool histogram_en)6061 int32_t QCamera2HardwareInterface::setHistogram(bool histogram_en)
6062 {
6063     return mParameters.setHistogram(histogram_en);
6064 }
6065 
6066 /*===========================================================================
6067  * FUNCTION   : setFaceDetection
6068  *
6069  * DESCRIPTION: set if face detection should be enabled
6070  *
6071  * PARAMETERS :
6072  *   @enabled : bool flag if face detection should be enabled
6073  *
6074  * RETURN     : int32_t type of status
6075  *              NO_ERROR  -- success
6076  *              none-zero failure code
6077  *==========================================================================*/
setFaceDetection(bool enabled)6078 int32_t QCamera2HardwareInterface::setFaceDetection(bool enabled)
6079 {
6080     return mParameters.setFaceDetection(enabled, true);
6081 }
6082 
6083 /*===========================================================================
6084  * FUNCTION   : isCaptureShutterEnabled
6085  *
6086  * DESCRIPTION: Check whether shutter should be triggered immediately after
6087  *              capture
6088  *
6089  * PARAMETERS :
6090  *
6091  * RETURN     : true - regular capture
6092  *              false - other type of capture
6093  *==========================================================================*/
isCaptureShutterEnabled()6094 bool QCamera2HardwareInterface::isCaptureShutterEnabled()
6095 {
6096     char prop[PROPERTY_VALUE_MAX];
6097     memset(prop, 0, sizeof(prop));
6098     property_get("persist.camera.feature.shutter", prop, "0");
6099     int enableShutter = atoi(prop);
6100     return enableShutter == 1;
6101 }
6102 
6103 /*===========================================================================
6104  * FUNCTION   : needProcessPreviewFrame
6105  *
6106  * DESCRIPTION: returns whether preview frame need to be displayed
6107  *
6108  * PARAMETERS :
6109  *
6110  * RETURN     : int32_t type of status
6111  *              NO_ERROR  -- success
6112  *              none-zero failure code
6113  *==========================================================================*/
needProcessPreviewFrame()6114 bool QCamera2HardwareInterface::needProcessPreviewFrame()
6115 {
6116     return m_stateMachine.isPreviewRunning()
6117             && mParameters.isDisplayFrameNeeded();
6118 };
6119 
6120 /*===========================================================================
6121  * FUNCTION   : prepareHardwareForSnapshot
6122  *
6123  * DESCRIPTION: prepare hardware for snapshot, such as LED
6124  *
6125  * PARAMETERS :
6126  *   @afNeeded: flag indicating if Auto Focus needs to be done during preparation
6127  *
6128  * RETURN     : int32_t type of status
6129  *              NO_ERROR  -- success
6130  *              none-zero failure code
6131  *==========================================================================*/
prepareHardwareForSnapshot(int32_t afNeeded)6132 int32_t QCamera2HardwareInterface::prepareHardwareForSnapshot(int32_t afNeeded)
6133 {
6134     CDBG_HIGH("[KPI Perf] %s: Prepare hardware such as LED",__func__);
6135     return mCameraHandle->ops->prepare_snapshot(mCameraHandle->camera_handle,
6136                                                 afNeeded);
6137 }
6138 
6139 /*===========================================================================
6140  * FUNCTION   : needFDMetadata
6141  *
6142  * DESCRIPTION: check whether we need process Face Detection metadata in this chanel
6143  *
6144  * PARAMETERS :
6145  *   @channel_type: channel type
6146  *
6147   * RETURN     : true: needed
6148  *              false: no need
6149  *==========================================================================*/
needFDMetadata(qcamera_ch_type_enum_t channel_type)6150 bool QCamera2HardwareInterface::needFDMetadata(qcamera_ch_type_enum_t channel_type)
6151 {
6152     //Note: Currently we only process ZSL channel
6153     bool value = false;
6154     if(channel_type == QCAMERA_CH_TYPE_ZSL){
6155         //check if FD requirement is enabled
6156         if(mParameters.isSnapshotFDNeeded() &&
6157            mParameters.isFaceDetectionEnabled()){
6158             value = true;
6159             CDBG_HIGH("%s: Face Detection metadata is required in ZSL mode.", __func__);
6160         }
6161     }
6162 
6163     return value;
6164 }
6165 
6166 /*===========================================================================
6167  * FUNCTION   : defferedWorkRoutine
6168  *
6169  * DESCRIPTION: data process routine that executes deffered tasks
6170  *
6171  * PARAMETERS :
6172  *   @data    : user data ptr (QCamera2HardwareInterface)
6173  *
6174  * RETURN     : None
6175  *==========================================================================*/
defferedWorkRoutine(void * obj)6176 void *QCamera2HardwareInterface::defferedWorkRoutine(void *obj)
6177 {
6178     int running = 1;
6179     int ret;
6180 
6181     QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)obj;
6182     QCameraCmdThread *cmdThread = &pme->mDefferedWorkThread;
6183 
6184     do {
6185         do {
6186             ret = cam_sem_wait(&cmdThread->cmd_sem);
6187             if (ret != 0 && errno != EINVAL) {
6188                 ALOGE("%s: cam_sem_wait error (%s)",
6189                            __func__, strerror(errno));
6190                 return NULL;
6191             }
6192         } while (ret != 0);
6193 
6194         // we got notified about new cmd avail in cmd queue
6195         camera_cmd_type_t cmd = cmdThread->getCmd();
6196         switch (cmd) {
6197         case CAMERA_CMD_TYPE_START_DATA_PROC:
6198             CDBG_HIGH("%s: start data proc", __func__);
6199             break;
6200         case CAMERA_CMD_TYPE_STOP_DATA_PROC:
6201             CDBG_HIGH("%s: stop data proc", __func__);
6202             // signal cmd is completed
6203             cam_sem_post(&cmdThread->sync_sem);
6204             break;
6205         case CAMERA_CMD_TYPE_DO_NEXT_JOB:
6206             {
6207                 DeffWork *dw =
6208                     reinterpret_cast<DeffWork *>(pme->mCmdQueue.dequeue());
6209 
6210                 if ( NULL == dw ) {
6211                     ALOGE("%s : Invalid deferred work", __func__);
6212                     break;
6213                 }
6214 
6215                 switch( dw->cmd ) {
6216                 case CMD_DEFF_ALLOCATE_BUFF:
6217                     {
6218                         QCameraChannel * pChannel = dw->args.allocArgs.ch;
6219 
6220                         if ( NULL == pChannel ) {
6221                             ALOGE("%s : Invalid deferred work channel",
6222                                     __func__);
6223                             break;
6224                         }
6225 
6226                         cam_stream_type_t streamType = dw->args.allocArgs.type;
6227 
6228                         uint32_t iNumOfStreams = pChannel->getNumOfStreams();
6229                         QCameraStream *pStream = NULL;
6230                         for ( uint32_t i = 0; i < iNumOfStreams; ++i) {
6231                             pStream = pChannel->getStreamByIndex(i);
6232 
6233                             if ( NULL == pStream ) {
6234                                 break;
6235                             }
6236 
6237                             if ( pStream->isTypeOf(streamType)) {
6238                                 if ( pStream->allocateBuffers() ) {
6239                                     ALOGE("%s: Error allocating buffers !!!",
6240                                             __func__);
6241                                 }
6242                                 break;
6243                             }
6244                         }
6245                         {
6246                             Mutex::Autolock l(pme->mDeffLock);
6247                             pme->mDeffOngoingJobs[dw->id] = false;
6248                             delete dw;
6249                             pme->mDeffCond.signal();
6250                         }
6251 
6252                     }
6253                     break;
6254                 case CMD_DEFF_PPROC_START:
6255                     {
6256                         QCameraChannel * pChannel = dw->args.pprocArgs;
6257                         assert(pChannel);
6258 
6259                         if (pme->m_postprocessor.start(pChannel) != NO_ERROR) {
6260                             ALOGE("%s: cannot start postprocessor", __func__);
6261                             pme->delChannel(QCAMERA_CH_TYPE_CAPTURE);
6262                         }
6263                         {
6264                             Mutex::Autolock l(pme->mDeffLock);
6265                             pme->mDeffOngoingJobs[dw->id] = false;
6266                             delete dw;
6267                             pme->mDeffCond.signal();
6268                         }
6269                     }
6270                     break;
6271                 default:
6272                     ALOGE("%s[%d]:  Incorrect command : %d",
6273                             __func__,
6274                             __LINE__,
6275                             dw->cmd);
6276                 }
6277             }
6278             break;
6279         case CAMERA_CMD_TYPE_EXIT:
6280             running = 0;
6281             break;
6282         default:
6283             break;
6284         }
6285     } while (running);
6286 
6287     return NULL;
6288 }
6289 
6290 /*===========================================================================
6291  * FUNCTION   : queueDefferedWork
6292  *
6293  * DESCRIPTION: function which queues deferred tasks
6294  *
6295  * PARAMETERS :
6296  *   @cmd     : deferred task
6297  *   @args    : deffered task arguments
6298  *
6299  * RETURN     : int32_t type of status
6300  *              NO_ERROR  -- success
6301  *              none-zero failure code
6302  *==========================================================================*/
queueDefferedWork(DefferedWorkCmd cmd,DefferWorkArgs args)6303 int32_t QCamera2HardwareInterface::queueDefferedWork(DefferedWorkCmd cmd,
6304                                                      DefferWorkArgs args)
6305 {
6306     Mutex::Autolock l(mDeffLock);
6307     for (int i = 0; i < MAX_ONGOING_JOBS; ++i) {
6308         if (!mDeffOngoingJobs[i]) {
6309             mCmdQueue.enqueue(new DeffWork(cmd, i, args));
6310             mDeffOngoingJobs[i] = true;
6311             mDefferedWorkThread.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB,
6312                     FALSE,
6313                     FALSE);
6314             return i;
6315         }
6316     }
6317     return -1;
6318 }
6319 
6320 /*===========================================================================
6321  * FUNCTION   : waitDefferedWork
6322  *
6323  * DESCRIPTION: waits for a deffered task to finish
6324  *
6325  * PARAMETERS :
6326  *   @job_id  : deferred task id
6327  *
6328  * RETURN     : int32_t type of status
6329  *              NO_ERROR  -- success
6330  *              none-zero failure code
6331  *==========================================================================*/
waitDefferedWork(int32_t & job_id)6332 int32_t QCamera2HardwareInterface::waitDefferedWork(int32_t &job_id)
6333 {
6334     Mutex::Autolock l(mDeffLock);
6335 
6336     if ((MAX_ONGOING_JOBS <= job_id) || (0 > job_id)) {
6337         return NO_ERROR;
6338     }
6339 
6340     while ( mDeffOngoingJobs[job_id] == true ) {
6341         mDeffCond.wait(mDeffLock);
6342     }
6343 
6344     job_id = MAX_ONGOING_JOBS;
6345     return NO_ERROR;
6346 }
6347 
6348 /*===========================================================================
6349  * FUNCTION   : isRegularCapture
6350  *
6351  * DESCRIPTION: Check configuration for regular catpure
6352  *
6353  * PARAMETERS :
6354  *
6355  * RETURN     : true - regular capture
6356  *              false - other type of capture
6357  *==========================================================================*/
isRegularCapture()6358 bool QCamera2HardwareInterface::isRegularCapture()
6359 {
6360     bool ret = false;
6361 
6362     if (numOfSnapshotsExpected() == 1 &&
6363         !isLongshotEnabled() &&
6364         !mParameters.getRecordingHintValue() &&
6365         !isZSLMode()) {
6366             ret = true;
6367     }
6368     return ret;
6369 }
6370 
6371 /*===========================================================================
6372  * FUNCTION   : getLogLevel
6373  *
6374  * DESCRIPTION: Reads the log level property into a variable
6375  *
6376  * PARAMETERS :
6377  *   None
6378  *
6379  * RETURN     :
6380  *   None
6381  *==========================================================================*/
getLogLevel()6382 void QCamera2HardwareInterface::getLogLevel()
6383 {
6384     char prop[PROPERTY_VALUE_MAX];
6385 
6386     property_get("persist.camera.logs", prop, "0");
6387     gCamHalLogLevel = atoi(prop);
6388 
6389     return;
6390 }
6391 
6392 }; // namespace qcamera
6393