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