• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
2  *
3  * Redistribution and use in source and binary forms, with or without
4  * modification, are permitted provided that the following conditions are
5  * met:
6  *     * Redistributions of source code must retain the above copyright
7  *       notice, this list of conditions and the following disclaimer.
8  *     * Redistributions in binary form must reproduce the above
9  *       copyright notice, this list of conditions and the following
10  *       disclaimer in the documentation and/or other materials provided
11  *       with the distribution.
12  *     * Neither the name of The Linux Foundation nor the names of its
13  *       contributors may be used to endorse or promote products derived
14  *       from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  */
29  
30  #define LOG_TAG "QCamera2HWI"
31  
32  // To remove
33  #include <cutils/properties.h>
34  
35  // System definitions
36  #include <utils/Errors.h>
37  #include <dlfcn.h>
38  #include <stdio.h>
39  #include <stdlib.h>
40  #include "gralloc_priv.h"
41  #include "native_handle.h"
42  
43  // Camera definitions
44  #include "android/QCamera2External.h"
45  #include "QCamera2HWI.h"
46  #include "QCameraBufferMaps.h"
47  #include "QCameraFlash.h"
48  #include "QCameraTrace.h"
49  
50  extern "C" {
51  #include "mm_camera_dbg.h"
52  }
53  
54  #define MAP_TO_DRIVER_COORDINATE(val, base, scale, offset) \
55      ((int32_t)val * (int32_t)scale / (int32_t)base + (int32_t)offset)
56  #define CAMERA_MIN_STREAMING_BUFFERS     3
57  #define EXTRA_ZSL_PREVIEW_STREAM_BUF     2
58  #define CAMERA_MIN_JPEG_ENCODING_BUFFERS 2
59  #define CAMERA_MIN_VIDEO_BUFFERS         9
60  #define CAMERA_MIN_CALLBACK_BUFFERS      5
61  #define CAMERA_LONGSHOT_STAGES           4
62  #define CAMERA_MIN_CAMERA_BATCH_BUFFERS  6
63  #define CAMERA_ISP_PING_PONG_BUFFERS     2
64  #define MIN_UNDEQUEUED_BUFFERS           1 // This is required if preview window is not set
65  #define CAMERA_MIN_DISPLAY_BUFFERS       2
66  #define CAMERA_DEFAULT_FPS               30000
67  
68  #define HDR_CONFIDENCE_THRESHOLD 0.4
69  
70  #define CAMERA_OPEN_PERF_TIME_OUT 500 // 500 milliseconds
71  
72  // Very long wait, just to be sure we don't deadlock
73  #define CAMERA_DEFERRED_THREAD_TIMEOUT 5000000000 // 5 seconds
74  #define CAMERA_DEFERRED_MAP_BUF_TIMEOUT 2000000000 // 2 seconds
75  #define CAMERA_MIN_METADATA_BUFFERS 10 // Need at least 10 for ZSL snapshot
76  #define CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS 5
77  #define CAMERA_MAX_PARAM_APPLY_DELAY 3
78  
79  namespace qcamera {
80  
81  extern cam_capability_t *gCamCapability[MM_CAMERA_MAX_NUM_SENSORS];
82  extern pthread_mutex_t gCamLock;
83  volatile uint32_t gCamHalLogLevel = 1;
84  extern uint8_t gNumCameraSessions;
85  uint32_t QCamera2HardwareInterface::sNextJobId = 1;
86  
87  camera_device_ops_t QCamera2HardwareInterface::mCameraOps = {
88      .set_preview_window =        QCamera2HardwareInterface::set_preview_window,
89      .set_callbacks =             QCamera2HardwareInterface::set_CallBacks,
90      .enable_msg_type =           QCamera2HardwareInterface::enable_msg_type,
91      .disable_msg_type =          QCamera2HardwareInterface::disable_msg_type,
92      .msg_type_enabled =          QCamera2HardwareInterface::msg_type_enabled,
93  
94      .start_preview =             QCamera2HardwareInterface::start_preview,
95      .stop_preview =              QCamera2HardwareInterface::stop_preview,
96      .preview_enabled =           QCamera2HardwareInterface::preview_enabled,
97      .store_meta_data_in_buffers= QCamera2HardwareInterface::store_meta_data_in_buffers,
98  
99      .start_recording =           QCamera2HardwareInterface::start_recording,
100      .stop_recording =            QCamera2HardwareInterface::stop_recording,
101      .recording_enabled =         QCamera2HardwareInterface::recording_enabled,
102      .release_recording_frame =   QCamera2HardwareInterface::release_recording_frame,
103  
104      .auto_focus =                QCamera2HardwareInterface::auto_focus,
105      .cancel_auto_focus =         QCamera2HardwareInterface::cancel_auto_focus,
106  
107      .take_picture =              QCamera2HardwareInterface::take_picture,
108      .cancel_picture =            QCamera2HardwareInterface::cancel_picture,
109  
110      .set_parameters =            QCamera2HardwareInterface::set_parameters,
111      .get_parameters =            QCamera2HardwareInterface::get_parameters,
112      .put_parameters =            QCamera2HardwareInterface::put_parameters,
113      .send_command =              QCamera2HardwareInterface::send_command,
114  
115      .release =                   QCamera2HardwareInterface::release,
116      .dump =                      QCamera2HardwareInterface::dump,
117  };
118  
119  /*===========================================================================
120   * FUNCTION   : set_preview_window
121   *
122   * DESCRIPTION: set preview window.
123   *
124   * PARAMETERS :
125   *   @device  : ptr to camera device struct
126   *   @window  : window ops table
127   *
128   * RETURN     : int32_t type of status
129   *              NO_ERROR  -- success
130   *              none-zero failure code
131   *==========================================================================*/
set_preview_window(struct camera_device * device,struct preview_stream_ops * window)132  int QCamera2HardwareInterface::set_preview_window(struct camera_device *device,
133          struct preview_stream_ops *window)
134  {
135      ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_SET_PREVIEW_WINDOW);
136      int rc = NO_ERROR;
137      QCamera2HardwareInterface *hw =
138          reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
139      if (!hw) {
140          LOGE("NULL camera device");
141          return BAD_VALUE;
142      }
143      LOGD("E camera id %d window = %p", hw->getCameraId(), window);
144  
145      hw->lockAPI();
146      qcamera_api_result_t apiResult;
147      rc = hw->processAPI(QCAMERA_SM_EVT_SET_PREVIEW_WINDOW, (void *)window);
148      if (rc == NO_ERROR) {
149          hw->waitAPIResult(QCAMERA_SM_EVT_SET_PREVIEW_WINDOW, &apiResult);
150          rc = apiResult.status;
151      }
152      hw->unlockAPI();
153      LOGD("X camera id %d", hw->getCameraId());
154  
155      return rc;
156  }
157  
158  /*===========================================================================
159   * FUNCTION   : set_CallBacks
160   *
161   * DESCRIPTION: set callbacks for notify and data
162   *
163   * PARAMETERS :
164   *   @device     : ptr to camera device struct
165   *   @notify_cb  : notify cb
166   *   @data_cb    : data cb
167   *   @data_cb_timestamp  : video data cd with timestamp
168   *   @get_memory : ops table for request gralloc memory
169   *   @user       : user data ptr
170   *
171   * RETURN     : none
172   *==========================================================================*/
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)173  void QCamera2HardwareInterface::set_CallBacks(struct camera_device *device,
174          camera_notify_callback notify_cb,
175          camera_data_callback data_cb,
176          camera_data_timestamp_callback data_cb_timestamp,
177          camera_request_memory get_memory,
178          void *user)
179  {
180      ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_SET_CALLBACKS);
181      QCamera2HardwareInterface *hw =
182          reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
183      if (!hw) {
184          LOGE("NULL camera device");
185          return;
186      }
187      LOGD("E camera id %d", hw->getCameraId());
188  
189      qcamera_sm_evt_setcb_payload_t payload;
190      payload.notify_cb = notify_cb;
191      payload.data_cb = data_cb;
192      payload.data_cb_timestamp = data_cb_timestamp;
193      payload.get_memory = get_memory;
194      payload.user = user;
195  
196      hw->lockAPI();
197      qcamera_api_result_t apiResult;
198      int32_t rc = hw->processAPI(QCAMERA_SM_EVT_SET_CALLBACKS, (void *)&payload);
199      if (rc == NO_ERROR) {
200          hw->waitAPIResult(QCAMERA_SM_EVT_SET_CALLBACKS, &apiResult);
201      }
202      hw->unlockAPI();
203      LOGD("X camera id %d", hw->getCameraId());
204  
205  }
206  
207  /*===========================================================================
208   * FUNCTION   : enable_msg_type
209   *
210   * DESCRIPTION: enable certain msg type
211   *
212   * PARAMETERS :
213   *   @device     : ptr to camera device struct
214   *   @msg_type   : msg type mask
215   *
216   * RETURN     : none
217   *==========================================================================*/
enable_msg_type(struct camera_device * device,int32_t msg_type)218  void QCamera2HardwareInterface::enable_msg_type(struct camera_device *device, int32_t msg_type)
219  {
220      ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_ENABLE_MSG_TYPE);
221      QCamera2HardwareInterface *hw =
222          reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
223      if (!hw) {
224          LOGE("NULL camera device");
225          return;
226      }
227      LOGD("E camera id %d", hw->getCameraId());
228  
229      hw->lockAPI();
230      qcamera_api_result_t apiResult;
231      int32_t rc = hw->processAPI(QCAMERA_SM_EVT_ENABLE_MSG_TYPE, (void *)&msg_type);
232      if (rc == NO_ERROR) {
233          hw->waitAPIResult(QCAMERA_SM_EVT_ENABLE_MSG_TYPE, &apiResult);
234      }
235      hw->unlockAPI();
236      LOGD("X camera id %d", hw->getCameraId());
237  
238  }
239  
240  /*===========================================================================
241   * FUNCTION   : disable_msg_type
242   *
243   * DESCRIPTION: disable certain msg type
244   *
245   * PARAMETERS :
246   *   @device     : ptr to camera device struct
247   *   @msg_type   : msg type mask
248   *
249   * RETURN     : none
250   *==========================================================================*/
disable_msg_type(struct camera_device * device,int32_t msg_type)251  void QCamera2HardwareInterface::disable_msg_type(struct camera_device *device, int32_t msg_type)
252  {
253      ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_DISABLE_MSG_TYPE);
254      QCamera2HardwareInterface *hw =
255          reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
256      if (!hw) {
257          LOGE("NULL camera device");
258          return;
259      }
260      LOGD("E camera id %d", hw->getCameraId());
261  
262      hw->lockAPI();
263      qcamera_api_result_t apiResult;
264      int32_t rc = hw->processAPI(QCAMERA_SM_EVT_DISABLE_MSG_TYPE, (void *)&msg_type);
265      if (rc == NO_ERROR) {
266          hw->waitAPIResult(QCAMERA_SM_EVT_DISABLE_MSG_TYPE, &apiResult);
267      }
268      hw->unlockAPI();
269      LOGD("X camera id %d", hw->getCameraId());
270  
271  }
272  
273  /*===========================================================================
274   * FUNCTION   : msg_type_enabled
275   *
276   * DESCRIPTION: if certain msg type is enabled
277   *
278   * PARAMETERS :
279   *   @device     : ptr to camera device struct
280   *   @msg_type   : msg type mask
281   *
282   * RETURN     : 1 -- enabled
283   *              0 -- not enabled
284   *==========================================================================*/
msg_type_enabled(struct camera_device * device,int32_t msg_type)285  int QCamera2HardwareInterface::msg_type_enabled(struct camera_device *device, int32_t msg_type)
286  {
287      ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_MSG_TYPE_ENABLED);
288      int ret = NO_ERROR;
289      QCamera2HardwareInterface *hw =
290          reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
291      if (!hw) {
292          LOGE("NULL camera device");
293          return BAD_VALUE;
294      }
295      LOGD("E camera id %d", hw->getCameraId());
296  
297      hw->lockAPI();
298      qcamera_api_result_t apiResult;
299      ret = hw->processAPI(QCAMERA_SM_EVT_MSG_TYPE_ENABLED, (void *)&msg_type);
300      if (ret == NO_ERROR) {
301          hw->waitAPIResult(QCAMERA_SM_EVT_MSG_TYPE_ENABLED, &apiResult);
302          ret = apiResult.enabled;
303      }
304      hw->unlockAPI();
305      LOGD("X camera id %d", hw->getCameraId());
306  
307     return ret;
308  }
309  
310  /*===========================================================================
311   * FUNCTION   : prepare_preview
312   *
313   * DESCRIPTION: prepare preview
314   *
315   * PARAMETERS :
316   *   @device  : ptr to camera device struct
317   *
318   * RETURN     : int32_t type of status
319   *              NO_ERROR  -- success
320   *              none-zero failure code
321   *==========================================================================*/
prepare_preview(struct camera_device * device)322  int QCamera2HardwareInterface::prepare_preview(struct camera_device *device)
323  {
324      ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PREPARE_PREVIEW);
325      int ret = NO_ERROR;
326      QCamera2HardwareInterface *hw =
327          reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
328      if (!hw) {
329          LOGE("NULL camera device");
330          return BAD_VALUE;
331      }
332      LOGH("[KPI Perf]: E PROFILE_PREPARE_PREVIEW camera id %d",
333               hw->getCameraId());
334      hw->lockAPI();
335      qcamera_api_result_t apiResult;
336      qcamera_sm_evt_enum_t evt = QCAMERA_SM_EVT_PREPARE_PREVIEW;
337      ret = hw->processAPI(evt, NULL);
338      if (ret == NO_ERROR) {
339          hw->waitAPIResult(evt, &apiResult);
340          ret = apiResult.status;
341      }
342      hw->unlockAPI();
343      LOGH("[KPI Perf]: X");
344      return ret;
345  }
346  
347  
348  /*===========================================================================
349   * FUNCTION   : start_preview
350   *
351   * DESCRIPTION: start preview
352   *
353   * PARAMETERS :
354   *   @device  : ptr to camera device struct
355   *
356   * RETURN     : int32_t type of status
357   *              NO_ERROR  -- success
358   *              none-zero failure code
359   *==========================================================================*/
start_preview(struct camera_device * device)360  int QCamera2HardwareInterface::start_preview(struct camera_device *device)
361  {
362      KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_START_PREVIEW);
363      int ret = NO_ERROR;
364      QCamera2HardwareInterface *hw =
365          reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
366      if (!hw) {
367          LOGE("NULL camera device");
368          return BAD_VALUE;
369      }
370      LOGI("[KPI Perf]: E PROFILE_START_PREVIEW camera id %d",
371               hw->getCameraId());
372  
373      hw->m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_START_PREVIEW);
374      hw->lockAPI();
375      qcamera_api_result_t apiResult;
376      qcamera_sm_evt_enum_t evt = QCAMERA_SM_EVT_START_PREVIEW;
377      if (hw->isNoDisplayMode()) {
378          evt = QCAMERA_SM_EVT_START_NODISPLAY_PREVIEW;
379      }
380      ret = hw->processAPI(evt, NULL);
381      if (ret == NO_ERROR) {
382          hw->waitAPIResult(evt, &apiResult);
383          ret = apiResult.status;
384      }
385      hw->unlockAPI();
386      hw->m_bPreviewStarted = true;
387      LOGI("[KPI Perf]: X ret = %d", ret);
388      return ret;
389  }
390  
391  /*===========================================================================
392   * FUNCTION   : stop_preview
393   *
394   * DESCRIPTION: stop preview
395   *
396   * PARAMETERS :
397   *   @device  : ptr to camera device struct
398   *
399   * RETURN     : none
400   *==========================================================================*/
stop_preview(struct camera_device * device)401  void QCamera2HardwareInterface::stop_preview(struct camera_device *device)
402  {
403      KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_STOP_PREVIEW);
404      QCamera2HardwareInterface *hw =
405          reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
406      if (!hw) {
407          LOGE("NULL camera device");
408          return;
409      }
410      LOGI("[KPI Perf]: E PROFILE_STOP_PREVIEW camera id %d",
411               hw->getCameraId());
412  
413      // Disable power Hint for preview
414      hw->m_perfLockMgr.releasePerfLock(PERF_LOCK_POWERHINT_PREVIEW);
415  
416      hw->m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_STOP_PREVIEW);
417  
418      hw->lockAPI();
419      qcamera_api_result_t apiResult;
420      int32_t ret = hw->processAPI(QCAMERA_SM_EVT_STOP_PREVIEW, NULL);
421      if (ret == NO_ERROR) {
422          hw->waitAPIResult(QCAMERA_SM_EVT_STOP_PREVIEW, &apiResult);
423      }
424      hw->unlockAPI();
425      LOGI("[KPI Perf]: X ret = %d", ret);
426  }
427  
428  /*===========================================================================
429   * FUNCTION   : preview_enabled
430   *
431   * DESCRIPTION: if preview is running
432   *
433   * PARAMETERS :
434   *   @device  : ptr to camera device struct
435   *
436   * RETURN     : 1 -- running
437   *              0 -- not running
438   *==========================================================================*/
preview_enabled(struct camera_device * device)439  int QCamera2HardwareInterface::preview_enabled(struct camera_device *device)
440  {
441      ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PREVIEW_ENABLED);
442      int ret = NO_ERROR;
443      QCamera2HardwareInterface *hw =
444          reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
445      if (!hw) {
446          LOGE("NULL camera device");
447          return BAD_VALUE;
448      }
449      LOGD("E camera id %d", hw->getCameraId());
450  
451      hw->lockAPI();
452      qcamera_api_result_t apiResult;
453      ret = hw->processAPI(QCAMERA_SM_EVT_PREVIEW_ENABLED, NULL);
454      if (ret == NO_ERROR) {
455          hw->waitAPIResult(QCAMERA_SM_EVT_PREVIEW_ENABLED, &apiResult);
456          ret = apiResult.enabled;
457      }
458  
459      //if preview enabled, can enable preview callback send
460      if(apiResult.enabled) {
461          hw->m_stateMachine.setPreviewCallbackNeeded(true);
462      }
463      hw->unlockAPI();
464      LOGD("X camera id %d", hw->getCameraId());
465  
466      return ret;
467  }
468  
469  /*===========================================================================
470   * FUNCTION   : store_meta_data_in_buffers
471   *
472   * DESCRIPTION: if need to store meta data in buffers for video frame
473   *
474   * PARAMETERS :
475   *   @device  : ptr to camera device struct
476   *   @enable  : flag if enable
477   *
478   * RETURN     : int32_t type of status
479   *              NO_ERROR  -- success
480   *              none-zero failure code
481   *==========================================================================*/
store_meta_data_in_buffers(struct camera_device * device,int enable)482  int QCamera2HardwareInterface::store_meta_data_in_buffers(
483                  struct camera_device *device, int enable)
484  {
485      int ret = NO_ERROR;
486      QCamera2HardwareInterface *hw =
487          reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
488      if (!hw) {
489          LOGE("NULL camera device");
490          return BAD_VALUE;
491      }
492      LOGD("E camera id %d", hw->getCameraId());
493  
494      hw->lockAPI();
495      qcamera_api_result_t apiResult;
496      ret = hw->processAPI(QCAMERA_SM_EVT_STORE_METADATA_IN_BUFS, (void *)&enable);
497      if (ret == NO_ERROR) {
498          hw->waitAPIResult(QCAMERA_SM_EVT_STORE_METADATA_IN_BUFS, &apiResult);
499          ret = apiResult.status;
500      }
501      hw->unlockAPI();
502      LOGD("X camera id %d", hw->getCameraId());
503  
504      return ret;
505  }
506  
507  /*===========================================================================
508   * FUNCTION   : restart_start_preview
509   *
510   * DESCRIPTION: start preview as part of the restart preview
511   *
512   * PARAMETERS :
513   *   @device  : ptr to camera device struct
514   *
515   * RETURN     : int32_t type of status
516   *              NO_ERROR  -- success
517   *              none-zero failure code
518   *==========================================================================*/
restart_start_preview(struct camera_device * device)519  int QCamera2HardwareInterface::restart_start_preview(struct camera_device *device)
520  {
521      ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_RESTART_START_PREVIEW);
522      int ret = NO_ERROR;
523      QCamera2HardwareInterface *hw =
524          reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
525      if (!hw) {
526          LOGE("NULL camera device");
527          return BAD_VALUE;
528      }
529      LOGI("E camera id %d", hw->getCameraId());
530      hw->lockAPI();
531      qcamera_api_result_t apiResult;
532  
533      if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
534          ret = hw->processAPI(QCAMERA_SM_EVT_RESTART_START_PREVIEW, NULL);
535          if (ret == NO_ERROR) {
536              hw->waitAPIResult(QCAMERA_SM_EVT_RESTART_START_PREVIEW, &apiResult);
537              ret = apiResult.status;
538          }
539      } else {
540          LOGE("This function is not supposed to be called in single-camera mode");
541          ret = INVALID_OPERATION;
542      }
543      // Preview restart done, update the mPreviewRestartNeeded flag to false.
544      hw->mPreviewRestartNeeded = false;
545      hw->unlockAPI();
546      LOGI("X camera id %d", hw->getCameraId());
547  
548      return ret;
549  }
550  
551  /*===========================================================================
552   * FUNCTION   : restart_stop_preview
553   *
554   * DESCRIPTION: stop preview as part of the restart preview
555   *
556   * PARAMETERS :
557   *   @device  : ptr to camera device struct
558   *
559   * RETURN     : int32_t type of status
560   *              NO_ERROR  -- success
561   *              none-zero failure code
562   *==========================================================================*/
restart_stop_preview(struct camera_device * device)563  int QCamera2HardwareInterface::restart_stop_preview(struct camera_device *device)
564  {
565      ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_RESTART_STOP_PREVIEW);
566      int ret = NO_ERROR;
567      QCamera2HardwareInterface *hw =
568          reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
569      if (!hw) {
570          LOGE("NULL camera device");
571          return BAD_VALUE;
572      }
573      LOGI("E camera id %d", hw->getCameraId());
574      hw->lockAPI();
575      qcamera_api_result_t apiResult;
576  
577      if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
578          ret = hw->processAPI(QCAMERA_SM_EVT_RESTART_STOP_PREVIEW, NULL);
579          if (ret == NO_ERROR) {
580              hw->waitAPIResult(QCAMERA_SM_EVT_RESTART_STOP_PREVIEW, &apiResult);
581              ret = apiResult.status;
582          }
583      } else {
584          LOGE("This function is not supposed to be called in single-camera mode");
585          ret = INVALID_OPERATION;
586      }
587  
588      hw->unlockAPI();
589      LOGI("X camera id %d", hw->getCameraId());
590  
591      return ret;
592  }
593  
594  /*===========================================================================
595   * FUNCTION   : pre_start_recording
596   *
597   * DESCRIPTION: prepare for the start recording
598   *
599   * PARAMETERS :
600   *   @device  : ptr to camera device struct
601   *
602   * RETURN     : int32_t type of status
603   *              NO_ERROR  -- success
604   *              none-zero failure code
605   *==========================================================================*/
pre_start_recording(struct camera_device * device)606  int QCamera2HardwareInterface::pre_start_recording(struct camera_device *device)
607  {
608      ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PRE_START_RECORDING);
609      int ret = NO_ERROR;
610      QCamera2HardwareInterface *hw =
611          reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
612      if (!hw) {
613          LOGE("NULL camera device");
614          return BAD_VALUE;
615      }
616      LOGH("[KPI Perf]: E PROFILE_PRE_START_RECORDING camera id %d",
617            hw->getCameraId());
618      hw->lockAPI();
619      qcamera_api_result_t apiResult;
620      ret = hw->processAPI(QCAMERA_SM_EVT_PRE_START_RECORDING, NULL);
621      if (ret == NO_ERROR) {
622          hw->waitAPIResult(QCAMERA_SM_EVT_PRE_START_RECORDING, &apiResult);
623          ret = apiResult.status;
624      }
625      hw->unlockAPI();
626      LOGH("[KPI Perf]: X");
627      return ret;
628  }
629  
630  /*===========================================================================
631   * FUNCTION   : start_recording
632   *
633   * DESCRIPTION: start recording
634   *
635   * PARAMETERS :
636   *   @device  : ptr to camera device struct
637   *
638   * RETURN     : int32_t type of status
639   *              NO_ERROR  -- success
640   *              none-zero failure code
641   *==========================================================================*/
start_recording(struct camera_device * device)642  int QCamera2HardwareInterface::start_recording(struct camera_device *device)
643  {
644      ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_START_RECORDING);
645      int ret = NO_ERROR;
646      QCamera2HardwareInterface *hw =
647          reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
648      if (!hw) {
649          LOGE("NULL camera device");
650          return BAD_VALUE;
651      }
652  
653      hw->m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_START_RECORDING);
654  
655      LOGI("[KPI Perf]: E PROFILE_START_RECORDING camera id %d",
656            hw->getCameraId());
657      // Give HWI control to call pre_start_recording in single camera mode.
658      // In dual-cam mode, this control belongs to muxer.
659      if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
660          ret = pre_start_recording(device);
661          if (ret != NO_ERROR) {
662              LOGE("pre_start_recording failed with ret = %d", ret);
663              hw->m_perfLockMgr.releasePerfLock(PERF_LOCK_START_RECORDING);
664              return ret;
665          }
666      }
667  
668      hw->lockAPI();
669      qcamera_api_result_t apiResult;
670      ret = hw->processAPI(QCAMERA_SM_EVT_START_RECORDING, NULL);
671      if (ret == NO_ERROR) {
672          hw->waitAPIResult(QCAMERA_SM_EVT_START_RECORDING, &apiResult);
673          ret = apiResult.status;
674      }
675      hw->unlockAPI();
676      hw->m_bRecordStarted = true;
677      LOGI("[KPI Perf]: X ret = %d", ret);
678  
679      return ret;
680  }
681  
682  /*===========================================================================
683   * FUNCTION   : stop_recording
684   *
685   * DESCRIPTION: stop recording
686   *
687   * PARAMETERS :
688   *   @device  : ptr to camera device struct
689   *
690   * RETURN     : none
691   *==========================================================================*/
stop_recording(struct camera_device * device)692  void QCamera2HardwareInterface::stop_recording(struct camera_device *device)
693  {
694      ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_STOP_RECORDING);
695      QCamera2HardwareInterface *hw =
696          reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
697      if (!hw) {
698          LOGE("NULL camera device");
699          return;
700      }
701  
702      hw->m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_STOP_RECORDING);
703  
704      LOGI("[KPI Perf]: E PROFILE_STOP_RECORDING camera id %d",
705               hw->getCameraId());
706  
707      hw->lockAPI();
708      qcamera_api_result_t apiResult;
709      int32_t ret = hw->processAPI(QCAMERA_SM_EVT_STOP_RECORDING, NULL);
710      if (ret == NO_ERROR) {
711          hw->waitAPIResult(QCAMERA_SM_EVT_STOP_RECORDING, &apiResult);
712      }
713      hw->unlockAPI();
714      LOGI("[KPI Perf]: X ret = %d", ret);
715  }
716  
717  /*===========================================================================
718   * FUNCTION   : recording_enabled
719   *
720   * DESCRIPTION: if recording is running
721   *
722   * PARAMETERS :
723   *   @device  : ptr to camera device struct
724   *
725   * RETURN     : 1 -- running
726   *              0 -- not running
727   *==========================================================================*/
recording_enabled(struct camera_device * device)728  int QCamera2HardwareInterface::recording_enabled(struct camera_device *device)
729  {
730      ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_RECORDING_ENABLED);
731      int ret = NO_ERROR;
732      QCamera2HardwareInterface *hw =
733          reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
734      if (!hw) {
735          LOGE("NULL camera device");
736          return BAD_VALUE;
737      }
738      LOGD("E camera id %d", hw->getCameraId());
739      hw->lockAPI();
740      qcamera_api_result_t apiResult;
741      ret = hw->processAPI(QCAMERA_SM_EVT_RECORDING_ENABLED, NULL);
742      if (ret == NO_ERROR) {
743          hw->waitAPIResult(QCAMERA_SM_EVT_RECORDING_ENABLED, &apiResult);
744          ret = apiResult.enabled;
745      }
746      hw->unlockAPI();
747      LOGD("X camera id %d", hw->getCameraId());
748  
749      return ret;
750  }
751  
752  /*===========================================================================
753   * FUNCTION   : release_recording_frame
754   *
755   * DESCRIPTION: return recording frame back
756   *
757   * PARAMETERS :
758   *   @device  : ptr to camera device struct
759   *   @opaque  : ptr to frame to be returned
760   *
761   * RETURN     : none
762   *==========================================================================*/
release_recording_frame(struct camera_device * device,const void * opaque)763  void QCamera2HardwareInterface::release_recording_frame(
764              struct camera_device *device, const void *opaque)
765  {
766      ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_REL_REC_FRAME);
767      int32_t ret = NO_ERROR;
768      QCamera2HardwareInterface *hw =
769          reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
770      if (!hw) {
771          LOGE("NULL camera device");
772          return;
773      }
774      if (!opaque) {
775          LOGE("Error!! Frame info is NULL");
776          return;
777      }
778      LOGD("E camera id %d", hw->getCameraId());
779  
780      hw->lockAPI();
781      qcamera_api_result_t apiResult;
782      ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, (void *)opaque);
783      if (ret == NO_ERROR) {
784          hw->waitAPIResult(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, &apiResult);
785      }
786      hw->unlockAPI();
787      LOGD("X camera id %d", hw->getCameraId());
788  }
789  
790  /*===========================================================================
791   * FUNCTION   : auto_focus
792   *
793   * DESCRIPTION: start auto focus
794   *
795   * PARAMETERS :
796   *   @device  : ptr to camera device struct
797   *
798   * RETURN     : int32_t type of status
799   *              NO_ERROR  -- success
800   *              none-zero failure code
801   *==========================================================================*/
auto_focus(struct camera_device * device)802  int QCamera2HardwareInterface::auto_focus(struct camera_device *device)
803  {
804      KPI_ATRACE_INT("Camera:AutoFocus", 1);
805      int ret = NO_ERROR;
806      QCamera2HardwareInterface *hw =
807          reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
808      if (!hw) {
809          LOGE("NULL camera device");
810          return BAD_VALUE;
811      }
812      LOGH("[KPI Perf] : E PROFILE_AUTO_FOCUS camera id %d",
813               hw->getCameraId());
814      hw->lockAPI();
815      qcamera_api_result_t apiResult;
816      ret = hw->processAPI(QCAMERA_SM_EVT_START_AUTO_FOCUS, NULL);
817      if (ret == NO_ERROR) {
818          hw->waitAPIResult(QCAMERA_SM_EVT_START_AUTO_FOCUS, &apiResult);
819          ret = apiResult.status;
820      }
821      hw->unlockAPI();
822      LOGH("[KPI Perf] : X ret = %d", ret);
823  
824      return ret;
825  }
826  
827  /*===========================================================================
828   * FUNCTION   : cancel_auto_focus
829   *
830   * DESCRIPTION: cancel auto focus
831   *
832   * PARAMETERS :
833   *   @device  : ptr to camera device struct
834   *
835   * RETURN     : int32_t type of status
836   *              NO_ERROR  -- success
837   *              none-zero failure code
838   *==========================================================================*/
cancel_auto_focus(struct camera_device * device)839  int QCamera2HardwareInterface::cancel_auto_focus(struct camera_device *device)
840  {
841      ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_CANCEL_AF);
842      int ret = NO_ERROR;
843      QCamera2HardwareInterface *hw =
844          reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
845      if (!hw) {
846          LOGE("NULL camera device");
847          return BAD_VALUE;
848      }
849      LOGH("[KPI Perf] : E PROFILE_CANCEL_AUTO_FOCUS camera id %d",
850               hw->getCameraId());
851      hw->lockAPI();
852      qcamera_api_result_t apiResult;
853      ret = hw->processAPI(QCAMERA_SM_EVT_STOP_AUTO_FOCUS, NULL);
854      if (ret == NO_ERROR) {
855          hw->waitAPIResult(QCAMERA_SM_EVT_STOP_AUTO_FOCUS, &apiResult);
856          ret = apiResult.status;
857      }
858      hw->unlockAPI();
859      LOGH("[KPI Perf] : X ret = %d", ret);
860      return ret;
861  }
862  
863  /*===========================================================================
864   * FUNCTION   : pre_take_picture
865   *
866   * DESCRIPTION: pre take picture, restart preview if necessary.
867   *
868   * PARAMETERS :
869   *   @device  : ptr to camera device struct
870   *
871   * RETURN     : int32_t type of status
872   *              NO_ERROR  -- success
873   *              none-zero failure code
874   *==========================================================================*/
pre_take_picture(struct camera_device * device)875  int QCamera2HardwareInterface::pre_take_picture(struct camera_device *device)
876  {
877      ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PRE_TAKE_PICTURE);
878      int ret = NO_ERROR;
879      QCamera2HardwareInterface *hw =
880          reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
881      if (!hw) {
882          LOGE("NULL camera device");
883          return BAD_VALUE;
884      }
885      LOGH("[KPI Perf]: E PROFILE_PRE_TAKE_PICTURE camera id %d",
886            hw->getCameraId());
887      hw->lockAPI();
888      qcamera_api_result_t apiResult;
889      ret = hw->processAPI(QCAMERA_SM_EVT_PRE_TAKE_PICTURE, NULL);
890      if (ret == NO_ERROR) {
891          hw->waitAPIResult(QCAMERA_SM_EVT_PRE_TAKE_PICTURE, &apiResult);
892          ret = apiResult.status;
893      }
894      hw->unlockAPI();
895      LOGH("[KPI Perf]: X");
896      return ret;
897  }
898  
899  /*===========================================================================
900   * FUNCTION   : take_picture
901   *
902   * DESCRIPTION: take picture
903   *
904   * PARAMETERS :
905   *   @device  : ptr to camera device struct
906   *
907   * RETURN     : int32_t type of status
908   *              NO_ERROR  -- success
909   *              none-zero failure code
910   *==========================================================================*/
take_picture(struct camera_device * device)911  int QCamera2HardwareInterface::take_picture(struct camera_device *device)
912  {
913      KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_TAKE_PICTURE);
914      int ret = NO_ERROR;
915      QCamera2HardwareInterface *hw =
916          reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
917      if (!hw) {
918          LOGE("NULL camera device");
919          return BAD_VALUE;
920      }
921      LOGI("[KPI Perf]: E PROFILE_TAKE_PICTURE camera id %d",
922               hw->getCameraId());
923  
924      // Acquire the perf lock for JPEG snapshot only
925      if (hw->mParameters.isJpegPictureFormat()) {
926          hw->m_perfLockMgr.acquirePerfLock(PERF_LOCK_TAKE_SNAPSHOT);
927      }
928  
929      qcamera_api_result_t apiResult;
930  
931     /** Added support for Retro-active Frames:
932       *  takePicture() is called before preparing Snapshot to indicate the
933       *  mm-camera-channel to pick up legacy frames even
934       *  before LED estimation is triggered.
935       */
936  
937      LOGH("isLiveSnap %d, isZSL %d, isHDR %d longshot = %d",
938             hw->isLiveSnapshot(), hw->isZSLMode(), hw->isHDRMode(),
939             hw->isLongshotEnabled());
940  
941      // Check for Retro-active Frames
942      if ((hw->mParameters.getNumOfRetroSnapshots() > 0) &&
943          !hw->isLiveSnapshot() && hw->isZSLMode() &&
944          !hw->isHDRMode() && !hw->isLongshotEnabled()) {
945          // Set Retro Picture Mode
946          hw->setRetroPicture(1);
947          hw->m_bLedAfAecLock = 0;
948          LOGL("Retro Enabled");
949  
950          // Give HWI control to call pre_take_picture in single camera mode.
951          // In dual-cam mode, this control belongs to muxer.
952          if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
953              ret = pre_take_picture(device);
954              if (ret != NO_ERROR) {
955                  LOGE("pre_take_picture failed with ret = %d",ret);
956                  return ret;
957              }
958          }
959  
960          /* Call take Picture for total number of snapshots required.
961               This includes the number of retro frames and normal frames */
962          hw->lockAPI();
963          ret = hw->processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL);
964          if (ret == NO_ERROR) {
965            // Wait for retro frames, before calling prepare snapshot
966            LOGD("Wait for Retro frames to be done");
967            hw->waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult);
968              ret = apiResult.status;
969          }
970          /* Unlock API since it is acquired in prepare snapshot seperately */
971          hw->unlockAPI();
972  
973          /* Prepare snapshot in case LED needs to be flashed */
974          LOGD("Start Prepare Snapshot");
975          ret = hw->prepare_snapshot(device);
976      }
977      else {
978          hw->setRetroPicture(0);
979          // Check if prepare snapshot is done
980          if (!hw->mPrepSnapRun) {
981              // Ignore the status from prepare_snapshot
982              hw->prepare_snapshot(device);
983          }
984  
985          // Give HWI control to call pre_take_picture in single camera mode.
986          // In dual-cam mode, this control belongs to muxer.
987          if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
988              ret = pre_take_picture(device);
989              if (ret != NO_ERROR) {
990                  LOGE("pre_take_picture failed with ret = %d",ret);
991                  return ret;
992              }
993          }
994  
995          // Regardless what the result value for prepare_snapshot,
996          // go ahead with capture anyway. Just like the way autofocus
997          // is handled in capture case
998          /* capture */
999          LOGL("Capturing normal frames");
1000          hw->lockAPI();
1001          ret = hw->processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL);
1002          if (ret == NO_ERROR) {
1003            hw->waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult);
1004              ret = apiResult.status;
1005          }
1006          hw->unlockAPI();
1007          if (!hw->isLongshotEnabled()){
1008              // For longshot mode, we prepare snapshot only once
1009              hw->mPrepSnapRun = false;
1010           }
1011      }
1012      LOGI("[KPI Perf]: X ret = %d", ret);
1013      return ret;
1014  }
1015  
1016  /*===========================================================================
1017   * FUNCTION   : cancel_picture
1018   *
1019   * DESCRIPTION: cancel current take picture request
1020   *
1021   * PARAMETERS :
1022   *   @device  : ptr to camera device struct
1023   *
1024   * RETURN     : int32_t type of status
1025   *              NO_ERROR  -- success
1026   *              none-zero failure code
1027   *==========================================================================*/
cancel_picture(struct camera_device * device)1028  int QCamera2HardwareInterface::cancel_picture(struct camera_device *device)
1029  {
1030      ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_CANCEL_PICTURE);
1031      int ret = NO_ERROR;
1032      QCamera2HardwareInterface *hw =
1033          reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1034      if (!hw) {
1035          LOGE("NULL camera device");
1036          return BAD_VALUE;
1037      }
1038      LOGI("[KPI Perf]: E PROFILE_CANCEL_PICTURE camera id %d",
1039               hw->getCameraId());
1040      hw->lockAPI();
1041      qcamera_api_result_t apiResult;
1042      ret = hw->processAPI(QCAMERA_SM_EVT_CANCEL_PICTURE, NULL);
1043      if (ret == NO_ERROR) {
1044          hw->waitAPIResult(QCAMERA_SM_EVT_CANCEL_PICTURE, &apiResult);
1045          ret = apiResult.status;
1046      }
1047      hw->unlockAPI();
1048      LOGI("[KPI Perf]: X camera id %d ret = %d", hw->getCameraId(), ret);
1049  
1050      return ret;
1051  }
1052  
1053  /*===========================================================================
1054   * FUNCTION   : set_parameters
1055   *
1056   * DESCRIPTION: set camera parameters
1057   *
1058   * PARAMETERS :
1059   *   @device  : ptr to camera device struct
1060   *   @parms   : string of packed parameters
1061   *
1062   * RETURN     : int32_t type of status
1063   *              NO_ERROR  -- success
1064   *              none-zero failure code
1065   *==========================================================================*/
set_parameters(struct camera_device * device,const char * parms)1066  int QCamera2HardwareInterface::set_parameters(struct camera_device *device,
1067                                                const char *parms)
1068  {
1069      ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_SET_PARAMETERS);
1070      int ret = NO_ERROR;
1071      QCamera2HardwareInterface *hw =
1072          reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1073      if (!hw) {
1074          LOGE("NULL camera device");
1075          return BAD_VALUE;
1076      }
1077      LOGD("E camera id %d", hw->getCameraId());
1078      hw->lockAPI();
1079      qcamera_api_result_t apiResult;
1080      ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS, (void *)parms);
1081      if (ret == NO_ERROR) {
1082          hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS, &apiResult);
1083          ret = apiResult.status;
1084      }
1085  
1086      // Give HWI control to restart (if necessary) after set params
1087      // in single camera mode. In dual-cam mode, this control belongs to muxer.
1088      if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
1089          if ((ret == NO_ERROR) && hw->getNeedRestart()) {
1090              LOGD("stopping after param change");
1091              ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_STOP, NULL);
1092              if (ret == NO_ERROR) {
1093                  hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_STOP, &apiResult);
1094                  ret = apiResult.status;
1095              }
1096          }
1097  
1098          if (ret == NO_ERROR) {
1099              LOGD("committing param change");
1100              ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, NULL);
1101              if (ret == NO_ERROR) {
1102                  hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, &apiResult);
1103                  ret = apiResult.status;
1104              }
1105          }
1106  
1107          if ((ret == NO_ERROR) && hw->getNeedRestart()) {
1108              LOGD("restarting after param change");
1109              ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_RESTART, NULL);
1110              if (ret == NO_ERROR) {
1111                  hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_RESTART, &apiResult);
1112                  ret = apiResult.status;
1113              }
1114          }
1115      }
1116  
1117      hw->unlockAPI();
1118      LOGD("X camera id %d ret %d", hw->getCameraId(), ret);
1119  
1120      return ret;
1121  }
1122  
1123  /*===========================================================================
1124   * FUNCTION   : stop_after_set_params
1125   *
1126   * DESCRIPTION: stop after a set param call, if necessary
1127   *
1128   * PARAMETERS :
1129   *   @device  : ptr to camera device struct
1130   *
1131   * RETURN     : int32_t type of status
1132   *              NO_ERROR  -- success
1133   *              none-zero failure code
1134   *==========================================================================*/
stop_after_set_params(struct camera_device * device)1135  int QCamera2HardwareInterface::stop_after_set_params(struct camera_device *device)
1136  {
1137      ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_STOP_AFTER_SET_PARAMS);
1138      int ret = NO_ERROR;
1139      QCamera2HardwareInterface *hw =
1140          reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1141      if (!hw) {
1142          LOGE("NULL camera device");
1143          return BAD_VALUE;
1144      }
1145      LOGD("E camera id %d", hw->getCameraId());
1146      hw->lockAPI();
1147      qcamera_api_result_t apiResult;
1148  
1149      if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
1150          ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_STOP, NULL);
1151          if (ret == NO_ERROR) {
1152              hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_STOP, &apiResult);
1153              ret = apiResult.status;
1154          }
1155      } else {
1156          LOGE("is not supposed to be called in single-camera mode");
1157          ret = INVALID_OPERATION;
1158      }
1159  
1160      hw->unlockAPI();
1161      LOGD("X camera id %d", hw->getCameraId());
1162  
1163      return ret;
1164  }
1165  
1166  /*===========================================================================
1167   * FUNCTION   : commit_params
1168   *
1169   * DESCRIPTION: commit after a set param call
1170   *
1171   * PARAMETERS :
1172   *   @device  : ptr to camera device struct
1173   *
1174   * RETURN     : int32_t type of status
1175   *              NO_ERROR  -- success
1176   *              none-zero failure code
1177   *==========================================================================*/
commit_params(struct camera_device * device)1178  int QCamera2HardwareInterface::commit_params(struct camera_device *device)
1179  {
1180      ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_COMMIT_PARAMS);
1181      int ret = NO_ERROR;
1182      QCamera2HardwareInterface *hw =
1183          reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1184      if (!hw) {
1185          LOGE("NULL camera device");
1186          return BAD_VALUE;
1187      }
1188      LOGD("E camera id %d", hw->getCameraId());
1189      hw->lockAPI();
1190      qcamera_api_result_t apiResult;
1191  
1192      if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
1193          ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, NULL);
1194          if (ret == NO_ERROR) {
1195              hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, &apiResult);
1196              ret = apiResult.status;
1197          }
1198      } else {
1199          LOGE("is not supposed to be called in single-camera mode");
1200          ret = INVALID_OPERATION;
1201      }
1202  
1203      hw->unlockAPI();
1204      LOGD("X camera id %d", hw->getCameraId());
1205  
1206      return ret;
1207  }
1208  
1209  /*===========================================================================
1210   * FUNCTION   : restart_after_set_params
1211   *
1212   * DESCRIPTION: restart after a set param call, if necessary
1213   *
1214   * PARAMETERS :
1215   *   @device  : ptr to camera device struct
1216   *
1217   * RETURN     : int32_t type of status
1218   *              NO_ERROR  -- success
1219   *              none-zero failure code
1220   *==========================================================================*/
restart_after_set_params(struct camera_device * device)1221  int QCamera2HardwareInterface::restart_after_set_params(struct camera_device *device)
1222  {
1223      ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_RESTART_AFTER_SET_PARAMS);
1224      int ret = NO_ERROR;
1225      QCamera2HardwareInterface *hw =
1226          reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1227      if (!hw) {
1228          LOGE("NULL camera device");
1229          return BAD_VALUE;
1230      }
1231      LOGD("E camera id %d", hw->getCameraId());
1232      hw->lockAPI();
1233      qcamera_api_result_t apiResult;
1234  
1235      if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
1236          ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_RESTART, NULL);
1237          if (ret == NO_ERROR) {
1238              hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_RESTART, &apiResult);
1239              ret = apiResult.status;
1240          }
1241      } else {
1242          LOGE("is not supposed to be called in single-camera mode");
1243          ret = INVALID_OPERATION;
1244      }
1245  
1246      hw->unlockAPI();
1247      LOGD("X camera id %d", hw->getCameraId());
1248      return ret;
1249  }
1250  
1251  /*===========================================================================
1252   * FUNCTION   : get_parameters
1253   *
1254   * DESCRIPTION: query camera parameters
1255   *
1256   * PARAMETERS :
1257   *   @device  : ptr to camera device struct
1258   *
1259   * RETURN     : packed parameters in a string
1260   *==========================================================================*/
get_parameters(struct camera_device * device)1261  char* QCamera2HardwareInterface::get_parameters(struct camera_device *device)
1262  {
1263      ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_GET_PARAMETERS);
1264      char *ret = NULL;
1265      QCamera2HardwareInterface *hw =
1266          reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1267      if (!hw) {
1268          LOGE("NULL camera device");
1269          return NULL;
1270      }
1271      LOGD("E camera id %d", hw->getCameraId());
1272      hw->lockAPI();
1273      qcamera_api_result_t apiResult;
1274      int32_t rc = hw->processAPI(QCAMERA_SM_EVT_GET_PARAMS, NULL);
1275      if (rc == NO_ERROR) {
1276          hw->waitAPIResult(QCAMERA_SM_EVT_GET_PARAMS, &apiResult);
1277          ret = apiResult.params;
1278      }
1279      hw->unlockAPI();
1280      LOGD("E camera id %d", hw->getCameraId());
1281  
1282      return ret;
1283  }
1284  
1285  /*===========================================================================
1286   * FUNCTION   : put_parameters
1287   *
1288   * DESCRIPTION: return camera parameters string back to HAL
1289   *
1290   * PARAMETERS :
1291   *   @device  : ptr to camera device struct
1292   *   @parm    : ptr to parameter string to be returned
1293   *
1294   * RETURN     : none
1295   *==========================================================================*/
put_parameters(struct camera_device * device,char * parm)1296  void QCamera2HardwareInterface::put_parameters(struct camera_device *device,
1297                                                 char *parm)
1298  {
1299      ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PUT_PARAMETERS);
1300      QCamera2HardwareInterface *hw =
1301          reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1302      if (!hw) {
1303          LOGE("NULL camera device");
1304          return;
1305      }
1306      LOGD("E camera id %d", hw->getCameraId());
1307      hw->lockAPI();
1308      qcamera_api_result_t apiResult;
1309      int32_t ret = hw->processAPI(QCAMERA_SM_EVT_PUT_PARAMS, (void *)parm);
1310      if (ret == NO_ERROR) {
1311          hw->waitAPIResult(QCAMERA_SM_EVT_PUT_PARAMS, &apiResult);
1312      }
1313      hw->unlockAPI();
1314      LOGD("E camera id %d", hw->getCameraId());
1315  }
1316  
1317  /*===========================================================================
1318   * FUNCTION   : send_command
1319   *
1320   * DESCRIPTION: command to be executed
1321   *
1322   * PARAMETERS :
1323   *   @device  : ptr to camera device struct
1324   *   @cmd     : cmd to be executed
1325   *   @arg1    : ptr to optional argument1
1326   *   @arg2    : ptr to optional argument2
1327   *
1328   * RETURN     : int32_t type of status
1329   *              NO_ERROR  -- success
1330   *              none-zero failure code
1331   *==========================================================================*/
send_command(struct camera_device * device,int32_t cmd,int32_t arg1,int32_t arg2)1332  int QCamera2HardwareInterface::send_command(struct camera_device *device,
1333                                              int32_t cmd,
1334                                              int32_t arg1,
1335                                              int32_t arg2)
1336  {
1337      ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_SEND_COMMAND);
1338      int ret = NO_ERROR;
1339      QCamera2HardwareInterface *hw =
1340          reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1341      if (!hw) {
1342          LOGE("NULL camera device");
1343          return BAD_VALUE;
1344      }
1345      LOGD("E camera id %d", hw->getCameraId());
1346  
1347      qcamera_sm_evt_command_payload_t payload;
1348      memset(&payload, 0, sizeof(qcamera_sm_evt_command_payload_t));
1349      payload.cmd = cmd;
1350      payload.arg1 = arg1;
1351      payload.arg2 = arg2;
1352      hw->lockAPI();
1353      qcamera_api_result_t apiResult;
1354      ret = hw->processAPI(QCAMERA_SM_EVT_SEND_COMMAND, (void *)&payload);
1355      if (ret == NO_ERROR) {
1356          hw->waitAPIResult(QCAMERA_SM_EVT_SEND_COMMAND, &apiResult);
1357          ret = apiResult.status;
1358      }
1359      hw->unlockAPI();
1360      LOGD("E camera id %d", hw->getCameraId());
1361  
1362      return ret;
1363  }
1364  
1365  /*===========================================================================
1366   * FUNCTION   : send_command_restart
1367   *
1368   * DESCRIPTION: restart if necessary after a send_command
1369   *
1370   * PARAMETERS :
1371   *   @device  : ptr to camera device struct
1372   *   @cmd     : cmd to be executed
1373   *   @arg1    : ptr to optional argument1
1374   *   @arg2    : ptr to optional argument2
1375   *
1376   * RETURN     : int32_t type of status
1377   *              NO_ERROR  -- success
1378   *              none-zero failure code
1379   *==========================================================================*/
send_command_restart(struct camera_device * device,int32_t cmd,int32_t arg1,int32_t arg2)1380  int QCamera2HardwareInterface::send_command_restart(struct camera_device *device,
1381          int32_t cmd,
1382          int32_t arg1,
1383          int32_t arg2)
1384  {
1385      ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_SEND_COMMAND_RESTART);
1386      int ret = NO_ERROR;
1387      QCamera2HardwareInterface *hw =
1388              reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1389      if (!hw) {
1390          LOGE("NULL camera device");
1391          return BAD_VALUE;
1392      }
1393  
1394      qcamera_sm_evt_command_payload_t payload;
1395      memset(&payload, 0, sizeof(qcamera_sm_evt_command_payload_t));
1396      payload.cmd = cmd;
1397      payload.arg1 = arg1;
1398      payload.arg2 = arg2;
1399      hw->lockAPI();
1400      qcamera_api_result_t apiResult;
1401      ret = hw->processAPI(QCAMERA_SM_EVT_SEND_COMMAND_RESTART, (void *)&payload);
1402      if (ret == NO_ERROR) {
1403          hw->waitAPIResult(QCAMERA_SM_EVT_SEND_COMMAND_RESTART, &apiResult);
1404          ret = apiResult.status;
1405      }
1406      hw->unlockAPI();
1407      LOGD("E camera id %d", hw->getCameraId());
1408  
1409      return ret;
1410  }
1411  
1412  /*===========================================================================
1413   * FUNCTION   : release
1414   *
1415   * DESCRIPTION: release camera resource
1416   *
1417   * PARAMETERS :
1418   *   @device  : ptr to camera device struct
1419   *
1420   * RETURN     : none
1421   *==========================================================================*/
release(struct camera_device * device)1422  void QCamera2HardwareInterface::release(struct camera_device *device)
1423  {
1424      ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_RELEASE);
1425      QCamera2HardwareInterface *hw =
1426          reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1427      if (!hw) {
1428          LOGE("NULL camera device");
1429          return;
1430      }
1431      LOGD("E camera id %d", hw->getCameraId());
1432      hw->lockAPI();
1433      qcamera_api_result_t apiResult;
1434      int32_t ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE, NULL);
1435      if (ret == NO_ERROR) {
1436          hw->waitAPIResult(QCAMERA_SM_EVT_RELEASE, &apiResult);
1437      }
1438      hw->unlockAPI();
1439      LOGD("E camera id %d", hw->getCameraId());
1440  }
1441  
1442  /*===========================================================================
1443   * FUNCTION   : dump
1444   *
1445   * DESCRIPTION: dump camera status
1446   *
1447   * PARAMETERS :
1448   *   @device  : ptr to camera device struct
1449   *   @fd      : fd for status to be dumped to
1450   *
1451   * RETURN     : int32_t type of status
1452   *              NO_ERROR  -- success
1453   *              none-zero failure code
1454   *==========================================================================*/
dump(struct camera_device * device,int fd)1455  int QCamera2HardwareInterface::dump(struct camera_device *device, int fd)
1456  {
1457      int ret = NO_ERROR;
1458  
1459      //Log level property is read when "adb shell dumpsys media.camera" is
1460      //called so that the log level can be controlled without restarting
1461      //media server
1462      getLogLevel();
1463      QCamera2HardwareInterface *hw =
1464          reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1465      if (!hw) {
1466          LOGE("NULL camera device");
1467          return BAD_VALUE;
1468      }
1469      LOGD("E camera id %d", hw->getCameraId());
1470      hw->lockAPI();
1471      qcamera_api_result_t apiResult;
1472      ret = hw->processAPI(QCAMERA_SM_EVT_DUMP, (void *)&fd);
1473      if (ret == NO_ERROR) {
1474          hw->waitAPIResult(QCAMERA_SM_EVT_DUMP, &apiResult);
1475          ret = apiResult.status;
1476      }
1477      hw->unlockAPI();
1478      LOGD("E camera id %d", hw->getCameraId());
1479  
1480      return ret;
1481  }
1482  
1483  /*===========================================================================
1484   * FUNCTION   : close_camera_device
1485   *
1486   * DESCRIPTION: close camera device
1487   *
1488   * PARAMETERS :
1489   *   @device  : ptr to camera device struct
1490   *
1491   * RETURN     : int32_t type of status
1492   *              NO_ERROR  -- success
1493   *              none-zero failure code
1494   *==========================================================================*/
close_camera_device(hw_device_t * hw_dev)1495  int QCamera2HardwareInterface::close_camera_device(hw_device_t *hw_dev)
1496  {
1497      KPI_ATRACE_CAMSCOPE_BEGIN(CAMSCOPE_HAL1_CLOSECAMERA);
1498      int ret = NO_ERROR;
1499  
1500      QCamera2HardwareInterface *hw =
1501          reinterpret_cast<QCamera2HardwareInterface *>(
1502              reinterpret_cast<camera_device_t *>(hw_dev)->priv);
1503      if (!hw) {
1504          LOGE("NULL camera device");
1505          return BAD_VALUE;
1506      }
1507      LOGI("[KPI Perf]: E camera id %d", hw->getCameraId());
1508      delete hw;
1509      LOGI("[KPI Perf]: X");
1510      KPI_ATRACE_CAMSCOPE_END(CAMSCOPE_HAL1_CLOSECAMERA);
1511      CAMSCOPE_DESTROY(CAMSCOPE_SECTION_HAL);
1512      return ret;
1513  }
1514  
1515  /*===========================================================================
1516   * FUNCTION   : register_face_image
1517   *
1518   * DESCRIPTION: register a face image into imaging lib for face authenticatio/
1519   *              face recognition
1520   *
1521   * PARAMETERS :
1522   *   @device  : ptr to camera device struct
1523   *   @img_ptr : ptr to image buffer
1524   *   @config  : ptr to config about input image, i.e., format, dimension, and etc.
1525   *
1526   * RETURN     : >=0 unique ID of face registerd.
1527   *              <0  failure.
1528   *==========================================================================*/
register_face_image(struct camera_device * device,void * img_ptr,cam_pp_offline_src_config_t * config)1529  int QCamera2HardwareInterface::register_face_image(struct camera_device *device,
1530                                                     void *img_ptr,
1531                                                     cam_pp_offline_src_config_t *config)
1532  {
1533      ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_REGISTER_FACE_IMAGE);
1534      int ret = NO_ERROR;
1535      QCamera2HardwareInterface *hw =
1536          reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1537      if (!hw) {
1538          LOGE("NULL camera device");
1539          return BAD_VALUE;
1540      }
1541      LOGD("E camera id %d", hw->getCameraId());
1542      qcamera_sm_evt_reg_face_payload_t payload;
1543      memset(&payload, 0, sizeof(qcamera_sm_evt_reg_face_payload_t));
1544      payload.img_ptr = img_ptr;
1545      payload.config = config;
1546      hw->lockAPI();
1547      qcamera_api_result_t apiResult;
1548      ret = hw->processAPI(QCAMERA_SM_EVT_REG_FACE_IMAGE, (void *)&payload);
1549      if (ret == NO_ERROR) {
1550          hw->waitAPIResult(QCAMERA_SM_EVT_REG_FACE_IMAGE, &apiResult);
1551          ret = apiResult.handle;
1552      }
1553      hw->unlockAPI();
1554      LOGD("E camera id %d", hw->getCameraId());
1555  
1556      return ret;
1557  }
1558  
1559  /*===========================================================================
1560   * FUNCTION   : prepare_snapshot
1561   *
1562   * DESCRIPTION: prepares hardware for snapshot
1563   *
1564   * PARAMETERS :
1565   *   @device  : ptr to camera device struct
1566   *
1567   * RETURN     : int32_t type of status
1568   *              NO_ERROR  -- success
1569   *              none-zero failure code
1570   *==========================================================================*/
prepare_snapshot(struct camera_device * device)1571  int QCamera2HardwareInterface::prepare_snapshot(struct camera_device *device)
1572  {
1573      ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PREPARE_SNAPSHOT);
1574      int ret = NO_ERROR;
1575      QCamera2HardwareInterface *hw =
1576          reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1577      if (!hw) {
1578          LOGE("NULL camera device");
1579          return BAD_VALUE;
1580      }
1581      if (hw->isLongshotEnabled() && hw->mPrepSnapRun == true) {
1582          // For longshot mode, we prepare snapshot only once
1583          LOGH("prepare snapshot only once ");
1584          return NO_ERROR;
1585      }
1586      LOGH("[KPI Perf]: E PROFILE_PREPARE_SNAPSHOT camera id %d",
1587               hw->getCameraId());
1588      hw->lockAPI();
1589      qcamera_api_result_t apiResult;
1590  
1591      /* Prepare snapshot in case LED needs to be flashed */
1592      if (hw->mFlashNeeded || hw->mParameters.isChromaFlashEnabled()) {
1593          /* Prepare snapshot in case LED needs to be flashed */
1594          ret = hw->processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL);
1595          if (ret == NO_ERROR) {
1596            hw->waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, &apiResult);
1597              ret = apiResult.status;
1598          }
1599          hw->mPrepSnapRun = true;
1600      }
1601      hw->unlockAPI();
1602      LOGH("[KPI Perf]: X, ret: %d", ret);
1603      return ret;
1604  }
1605  
1606  /*===========================================================================
1607   * FUNCTION   : QCamera2HardwareInterface
1608   *
1609   * DESCRIPTION: constructor of QCamera2HardwareInterface
1610   *
1611   * PARAMETERS :
1612   *   @cameraId  : camera ID
1613   *
1614   * RETURN     : none
1615   *==========================================================================*/
QCamera2HardwareInterface(uint32_t cameraId)1616  QCamera2HardwareInterface::QCamera2HardwareInterface(uint32_t cameraId)
1617      : mCameraId(cameraId),
1618        mCameraHandle(NULL),
1619        mMasterCamera(CAM_TYPE_MAIN),
1620        mCameraOpened(false),
1621        mDualCamera(false),
1622        m_pFovControl(NULL),
1623        m_bRelCamCalibValid(false),
1624        mPreviewWindow(NULL),
1625        mMsgEnabled(0),
1626        mStoreMetaDataInFrame(0),
1627        mJpegCb(NULL),
1628        mCallbackCookie(NULL),
1629        mJpegCallbackCookie(NULL),
1630        m_bMpoEnabled(TRUE),
1631        m_stateMachine(this),
1632        m_smThreadActive(true),
1633        m_postprocessor(this),
1634        m_thermalAdapter(QCameraThermalAdapter::getInstance()),
1635        m_cbNotifier(this),
1636        m_perfLockMgr(),
1637        m_bPreviewStarted(false),
1638        m_bRecordStarted(false),
1639        m_currentFocusState(CAM_AF_STATE_INACTIVE),
1640        mDumpFrmCnt(0U),
1641        mDumpSkipCnt(0U),
1642        mThermalLevel(QCAMERA_THERMAL_NO_ADJUSTMENT),
1643        mActiveAF(false),
1644        m_HDRSceneEnabled(false),
1645        mLongshotEnabled(false),
1646        mLiveSnapshotThread(0),
1647        mIntPicThread(0),
1648        mFlashNeeded(false),
1649        mFlashConfigured(false),
1650        mDeviceRotation(0U),
1651        mCaptureRotation(0U),
1652        mJpegExifRotation(0U),
1653        mUseJpegExifRotation(false),
1654        mIs3ALocked(false),
1655        mPrepSnapRun(false),
1656        mZoomLevel(0),
1657        mPreviewRestartNeeded(false),
1658        mVFrameCount(0),
1659        mVLastFrameCount(0),
1660        mVLastFpsTime(0),
1661        mVFps(0),
1662        mPFrameCount(0),
1663        mPLastFrameCount(0),
1664        mPLastFpsTime(0),
1665        mPFps(0),
1666        mLowLightConfigured(false),
1667        mInstantAecFrameCount(0),
1668        m_bIntJpegEvtPending(false),
1669        m_bIntRawEvtPending(false),
1670        mReprocJob(0),
1671        mJpegJob(0),
1672        mMetadataAllocJob(0),
1673        mInitPProcJob(0),
1674        mParamAllocJob(0),
1675        mParamInitJob(0),
1676        mOutputCount(0),
1677        mInputCount(0),
1678        mAdvancedCaptureConfigured(false),
1679        mHDRBracketingEnabled(false),
1680        mNumPreviewFaces(-1),
1681        mJpegClientHandle(0),
1682        mJpegHandleOwner(false),
1683        mMetadataMem(NULL),
1684        mCACDoneReceived(false),
1685        m_bNeedRestart(false),
1686        mBootToMonoTimestampOffset(0),
1687        bDepthAFCallbacks(true),
1688        m_bNeedHalPP(FALSE)
1689  {
1690  #ifdef TARGET_TS_MAKEUP
1691      memset(&mFaceRect, -1, sizeof(mFaceRect));
1692  #endif
1693      getLogLevel();
1694      ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_QCAMERA2HWI);
1695      mCameraDevice.common.tag = HARDWARE_DEVICE_TAG;
1696      mCameraDevice.common.version = HARDWARE_DEVICE_API_VERSION(1, 0);
1697      mCameraDevice.common.close = close_camera_device;
1698      mCameraDevice.ops = &mCameraOps;
1699      mCameraDevice.priv = this;
1700  
1701      mDualCamera = is_dual_camera_by_idx(cameraId);
1702  
1703      pthread_mutex_init(&m_lock, NULL);
1704      pthread_cond_init(&m_cond, NULL);
1705  
1706      m_apiResultList = NULL;
1707  
1708      pthread_mutex_init(&m_evtLock, NULL);
1709      pthread_cond_init(&m_evtCond, NULL);
1710      memset(&m_evtResult, 0, sizeof(qcamera_api_result_t));
1711  
1712  
1713      pthread_mutex_init(&m_int_lock, NULL);
1714      pthread_cond_init(&m_int_cond, NULL);
1715  
1716      memset(m_channels, 0, sizeof(m_channels));
1717  
1718      memset(&mExifParams, 0, sizeof(mm_jpeg_exif_params_t));
1719  
1720      memset(m_BackendFileName, 0, QCAMERA_MAX_FILEPATH_LENGTH);
1721  
1722      memset(mDefOngoingJobs, 0, sizeof(mDefOngoingJobs));
1723      memset(&mJpegMetadata, 0, sizeof(mJpegMetadata));
1724      memset(&mJpegHandle, 0, sizeof(mJpegHandle));
1725      memset(&mJpegMpoHandle, 0, sizeof(mJpegMpoHandle));
1726  
1727      mDeferredWorkThread.launch(deferredWorkRoutine, this);
1728      mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_START_DATA_PROC, FALSE, FALSE);
1729  
1730      pthread_mutex_init(&mGrallocLock, NULL);
1731      mEnqueuedBuffers = 0;
1732      mFrameSkipStart = 0;
1733      mFrameSkipEnd = 0;
1734      mLastPreviewFrameID = 0;
1735  
1736      //Load and read GPU library.
1737      lib_surface_utils = NULL;
1738      LINK_get_surface_pixel_alignment = NULL;
1739      mSurfaceStridePadding = CAM_PAD_TO_32;
1740      lib_surface_utils = dlopen("libadreno_utils.so", RTLD_NOW);
1741      if (lib_surface_utils) {
1742          *(void **)&LINK_get_surface_pixel_alignment =
1743                  dlsym(lib_surface_utils, "get_gpu_pixel_alignment");
1744           if (LINK_get_surface_pixel_alignment) {
1745               mSurfaceStridePadding = LINK_get_surface_pixel_alignment();
1746           }
1747           dlclose(lib_surface_utils);
1748      }
1749  }
1750  
1751  /*===========================================================================
1752   * FUNCTION   : ~QCamera2HardwareInterface
1753   *
1754   * DESCRIPTION: destructor of QCamera2HardwareInterface
1755   *
1756   * PARAMETERS : none
1757   *
1758   * RETURN     : none
1759   *==========================================================================*/
~QCamera2HardwareInterface()1760  QCamera2HardwareInterface::~QCamera2HardwareInterface()
1761  {
1762      LOGH("E");
1763  
1764      mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_STOP_DATA_PROC, TRUE, TRUE);
1765      mDeferredWorkThread.exit();
1766  
1767      if (mMetadataMem != NULL) {
1768          delete mMetadataMem;
1769          mMetadataMem = NULL;
1770      }
1771  
1772      if (m_pFovControl) {
1773          delete m_pFovControl;
1774          m_pFovControl = NULL;
1775      }
1776  
1777      m_perfLockMgr.acquirePerfLock(PERF_LOCK_CLOSE_CAMERA);
1778      lockAPI();
1779      m_smThreadActive = false;
1780      unlockAPI();
1781      m_stateMachine.releaseThread();
1782      closeCamera();
1783      m_perfLockMgr.releasePerfLock(PERF_LOCK_CLOSE_CAMERA);
1784  
1785      pthread_mutex_destroy(&m_lock);
1786      pthread_cond_destroy(&m_cond);
1787      pthread_mutex_destroy(&m_evtLock);
1788      pthread_cond_destroy(&m_evtCond);
1789      pthread_mutex_destroy(&m_int_lock);
1790      pthread_cond_destroy(&m_int_cond);
1791      pthread_mutex_destroy(&mGrallocLock);
1792      LOGH("X");
1793  }
1794  
1795  /*===========================================================================
1796   * FUNCTION   : deferPPInit
1797   *
1798   * DESCRIPTION: Queue postproc init task to deferred thread
1799   *
1800   * PARAMETERS : none
1801   *
1802   * RETURN     : uint32_t job id of pproc init job
1803   *              0  -- failure
1804   *==========================================================================*/
deferPPInit()1805  uint32_t QCamera2HardwareInterface::deferPPInit()
1806  {
1807      // init pproc
1808      DeferWorkArgs args;
1809      DeferPProcInitArgs pprocInitArgs;
1810  
1811      memset(&args, 0, sizeof(DeferWorkArgs));
1812      memset(&pprocInitArgs, 0, sizeof(DeferPProcInitArgs));
1813  
1814      pprocInitArgs.jpeg_cb = jpegEvtHandle;
1815      pprocInitArgs.user_data = this;
1816      args.pprocInitArgs = pprocInitArgs;
1817  
1818      return queueDeferredWork(CMD_DEF_PPROC_INIT,
1819              args);
1820  }
1821  
1822  /*===========================================================================
1823   * FUNCTION   : openCamera
1824   *
1825   * DESCRIPTION: open camera
1826   *
1827   * PARAMETERS :
1828   *   @hw_device  : double ptr for camera device struct
1829   *
1830   * RETURN     : int32_t type of status
1831   *              NO_ERROR  -- success
1832   *              none-zero failure code
1833   *==========================================================================*/
openCamera(struct hw_device_t ** hw_device)1834  int QCamera2HardwareInterface::openCamera(struct hw_device_t **hw_device)
1835  {
1836      KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_OPENCAMERA);
1837      int rc = NO_ERROR;
1838      if (mCameraOpened) {
1839          *hw_device = NULL;
1840          LOGE("Permission Denied");
1841          return PERMISSION_DENIED;
1842      }
1843      LOGI("[KPI Perf]: E PROFILE_OPEN_CAMERA camera id %d",
1844              mCameraId);
1845  
1846      m_perfLockMgr.acquirePerfLock(PERF_LOCK_OPEN_CAMERA);
1847  
1848      rc = openCamera();
1849      if (rc == NO_ERROR){
1850          *hw_device = &mCameraDevice.common;
1851          if (m_thermalAdapter.init(this) != 0) {
1852            LOGW("Init thermal adapter failed");
1853          }
1854      }
1855      else
1856          *hw_device = NULL;
1857  
1858      LOGI("[KPI Perf]: X PROFILE_OPEN_CAMERA camera id %d, rc: %d",
1859              mCameraId, rc);
1860  
1861      return rc;
1862  }
1863  
1864  /*===========================================================================
1865   * FUNCTION   : openCamera
1866   *
1867   * DESCRIPTION: open camera
1868   *
1869   * PARAMETERS : none
1870   *
1871   * RETURN     : int32_t type of status
1872   *              NO_ERROR  -- success
1873   *              none-zero failure code
1874   *==========================================================================*/
openCamera()1875  int QCamera2HardwareInterface::openCamera()
1876  {
1877      int32_t rc = NO_ERROR;
1878      char value[PROPERTY_VALUE_MAX];
1879  
1880      if (mCameraHandle) {
1881          LOGE("Failure: Camera already opened");
1882          return ALREADY_EXISTS;
1883      }
1884  
1885      rc = QCameraFlash::getInstance().reserveFlashForCamera(mCameraId);
1886      if (rc < 0) {
1887          LOGE("Failed to reserve flash for camera id: %d",
1888                  mCameraId);
1889          return UNKNOWN_ERROR;
1890      }
1891  
1892      // alloc param buffer
1893      DeferWorkArgs args;
1894      memset(&args, 0, sizeof(args));
1895      mParamAllocJob = queueDeferredWork(CMD_DEF_PARAM_ALLOC, args);
1896      if (mParamAllocJob == 0) {
1897          LOGE("Failed queueing PARAM_ALLOC job");
1898          return -ENOMEM;
1899      }
1900  
1901      if (gCamCapability[mCameraId] != NULL) {
1902          // allocate metadata buffers
1903          DeferWorkArgs args;
1904          DeferMetadataAllocArgs metadataAllocArgs;
1905  
1906          memset(&args, 0, sizeof(args));
1907          memset(&metadataAllocArgs, 0, sizeof(metadataAllocArgs));
1908  
1909          uint32_t padding =
1910                  gCamCapability[mCameraId]->padding_info.plane_padding;
1911          metadataAllocArgs.size = PAD_TO_SIZE(sizeof(metadata_buffer_t),
1912                  padding);
1913          metadataAllocArgs.bufferCnt = CAMERA_MIN_METADATA_BUFFERS;
1914          args.metadataAllocArgs = metadataAllocArgs;
1915  
1916          mMetadataAllocJob = queueDeferredWork(CMD_DEF_METADATA_ALLOC, args);
1917          if (mMetadataAllocJob == 0) {
1918              LOGE("Failed to allocate metadata buffer");
1919              rc = -ENOMEM;
1920              goto error_exit1;
1921          }
1922  
1923          rc = camera_open((uint8_t)mCameraId, &mCameraHandle);
1924          if (rc) {
1925              LOGE("camera_open failed. rc = %d, mCameraHandle = %p",
1926                       rc, mCameraHandle);
1927              goto error_exit2;
1928          }
1929  
1930          mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle,
1931                  camEvtHandle,
1932                  (void *) this);
1933      } else {
1934          LOGH("Capabilities not inited, initializing now.");
1935  
1936          rc = camera_open((uint8_t)mCameraId, &mCameraHandle);
1937          if (rc) {
1938              LOGE("camera_open failed. rc = %d, mCameraHandle = %p",
1939                       rc, mCameraHandle);
1940              goto error_exit2;
1941          }
1942  
1943          if(NO_ERROR != initCapabilities(mCameraId,mCameraHandle)) {
1944              LOGE("initCapabilities failed.");
1945              rc = UNKNOWN_ERROR;
1946              goto error_exit3;
1947          }
1948  
1949          mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle,
1950                  camEvtHandle,
1951                  (void *) this);
1952      }
1953      mBundledSnapshot = 0;
1954      mActiveCameras = MM_CAMERA_TYPE_MAIN;
1955      if (isDualCamera()) {
1956          mActiveCameras |= MM_CAMERA_TYPE_AUX;
1957  
1958          // Create and initialize FOV-control object
1959          m_pFovControl = QCameraFOVControl::create(gCamCapability[mCameraId]->main_cam_cap,
1960                  gCamCapability[mCameraId]->aux_cam_cap);
1961          if (m_pFovControl) {
1962              *gCamCapability[mCameraId] = m_pFovControl->consolidateCapabilities(
1963                      gCamCapability[mCameraId]->main_cam_cap,
1964                      gCamCapability[mCameraId]->aux_cam_cap);
1965          } else {
1966              LOGE("FOV-control: Failed to create an object");
1967              rc = NO_MEMORY;
1968              goto error_exit3;
1969          }
1970      }
1971  
1972      // Init params in the background
1973      // 1. It's safe to queue init job, even if alloc job is not yet complete.
1974      // It will be queued to the same thread, so the alloc is guaranteed to
1975      // finish first.
1976      // 2. However, it is not safe to begin param init until after camera is
1977      // open. That is why we wait until after camera open completes to schedule
1978      // this task.
1979      memset(&args, 0, sizeof(args));
1980      mParamInitJob = queueDeferredWork(CMD_DEF_PARAM_INIT, args);
1981      if (mParamInitJob == 0) {
1982          LOGE("Failed queuing PARAM_INIT job");
1983          rc = -ENOMEM;
1984          goto error_exit3;
1985      }
1986  
1987      mCameraOpened = true;
1988  
1989      //Notify display HAL that a camera session is active.
1990      //But avoid calling the same during bootup because camera service might open/close
1991      //cameras at boot time during its initialization and display service will also internally
1992      //wait for camera service to initialize first while calling this display API, resulting in a
1993      //deadlock situation. Since boot time camera open/close calls are made only to fetch
1994      //capabilities, no need of this display bw optimization.
1995      //Use "service.bootanim.exit" property to know boot status.
1996      property_get("service.bootanim.exit", value, "0");
1997      if (atoi(value) == 1) {
1998          pthread_mutex_lock(&gCamLock);
1999          if (gNumCameraSessions++ == 0) {
2000              setCameraLaunchStatus(true);
2001          }
2002          pthread_mutex_unlock(&gCamLock);
2003      }
2004  
2005      // Setprop to decide the time source (whether boottime or monotonic).
2006      // By default, use monotonic time.
2007      property_get("persist.camera.time.monotonic", value, "1");
2008      mBootToMonoTimestampOffset = 0;
2009      if (atoi(value) == 1) {
2010          // if monotonic is set, then need to use time in monotonic.
2011          // So, Measure the clock offset between BOOTTIME and MONOTONIC
2012          // The clock domain source for ISP is BOOTTIME and
2013          // for Video/display is MONOTONIC
2014          // The below offset is used to convert from clock domain of other subsystem
2015          // (video/hardware composer) to that of camera. Assumption is that this
2016          // offset won't change during the life cycle of the camera device. In other
2017          // words, camera device shouldn't be open during CPU suspend.
2018          mBootToMonoTimestampOffset = getBootToMonoTimeOffset();
2019      }
2020      LOGH("mBootToMonoTimestampOffset = %lld", mBootToMonoTimestampOffset);
2021  
2022      memset(value, 0, sizeof(value));
2023      property_get("persist.camera.depth.focus.cb", value, "1");
2024      bDepthAFCallbacks = atoi(value);
2025  
2026      memset(value, 0, sizeof(value));
2027      property_get("persist.camera.cache.optimize", value, "1");
2028      m_bOptimizeCacheOps = atoi(value);
2029  
2030      return NO_ERROR;
2031  
2032  error_exit3:
2033      if(mJpegClientHandle) {
2034          deinitJpegHandle();
2035      }
2036      mCameraHandle->ops->close_camera(mCameraHandle->camera_handle);
2037      mCameraHandle = NULL;
2038  error_exit2:
2039      waitDeferredWork(mMetadataAllocJob);
2040  error_exit1:
2041      waitDeferredWork(mParamAllocJob);
2042      return rc;
2043  
2044  }
2045  
2046  /*===========================================================================
2047   * FUNCTION   : bundleRelatedCameras
2048   *
2049   * DESCRIPTION: bundle cameras to enable syncing of cameras
2050   *
2051   * PARAMETERS :
2052   *   @sync        :indicates whether syncing is On or Off
2053   *
2054   * RETURN     : int32_t type of status
2055   *              NO_ERROR  -- success
2056   *              none-zero failure code
2057   *==========================================================================*/
bundleRelatedCameras(bool syncOn)2058  int QCamera2HardwareInterface::bundleRelatedCameras(bool syncOn)
2059  {
2060      int32_t rc = mParameters.bundleRelatedCameras(syncOn);
2061      if (rc != NO_ERROR) {
2062          LOGE("bundleRelatedCameras failed %d", rc);
2063          return rc;
2064      }
2065      return rc;
2066  }
2067  
2068  /*===========================================================================
2069   * FUNCTION   : getCameraSessionId
2070   *
2071   * DESCRIPTION: gets the backend session Id of this HWI instance
2072   *
2073   * PARAMETERS :
2074   *   @sessionid  : pointer to the output session id
2075   *
2076   * RETURN     : int32_t type of status
2077   *              NO_ERROR  -- success
2078   *              none-zero failure code
2079   *==========================================================================*/
getCameraSessionId(uint32_t * session_id)2080  int QCamera2HardwareInterface::getCameraSessionId(uint32_t* session_id)
2081  {
2082      int32_t rc = NO_ERROR;
2083  
2084      if(session_id != NULL) {
2085          rc = mCameraHandle->ops->get_session_id(mCameraHandle->camera_handle,
2086                  session_id);
2087          LOGD("Getting Camera Session Id %d", *session_id);
2088      } else {
2089          LOGE("Session Id is Null");
2090          return UNKNOWN_ERROR;
2091      }
2092      return rc;
2093  }
2094  
2095  /*===========================================================================
2096   * FUNCTION   : isFrameSyncEnabled
2097   *
2098   * DESCRIPTION: returns whether frame sync is enabled
2099   *
2100   * PARAMETERS : none
2101   *
2102   * RETURN     : bool indicating whether frame sync is enabled
2103   *==========================================================================*/
isFrameSyncEnabled(void)2104  bool QCamera2HardwareInterface::isFrameSyncEnabled(void)
2105  {
2106      return mParameters.isFrameSyncEnabled();
2107  }
2108  
2109  /*===========================================================================
2110   * FUNCTION   : setFrameSyncEnabled
2111   *
2112   * DESCRIPTION: sets whether frame sync is enabled
2113   *
2114   * PARAMETERS :
2115   *   @enable  : flag whether to enable or disable frame sync
2116   *
2117   * RETURN     : int32_t type of status
2118   *              NO_ERROR  -- success
2119   *              none-zero failure code
2120   *==========================================================================*/
setFrameSyncEnabled(bool enable)2121  int32_t QCamera2HardwareInterface::setFrameSyncEnabled(bool enable)
2122  {
2123      return mParameters.setFrameSyncEnabled(enable);
2124  }
2125  
2126  /*===========================================================================
2127   * FUNCTION   : getRelatedCamSyncInfo
2128   *
2129   * DESCRIPTION:returns the related cam sync info for this HWI instance
2130   *
2131   * PARAMETERS :none
2132   *
2133   * RETURN     : const pointer to cam_sync_related_sensors_event_info_t
2134   *==========================================================================*/
2135  const cam_sync_related_sensors_event_info_t*
getRelatedCamSyncInfo(void)2136          QCamera2HardwareInterface::getRelatedCamSyncInfo(void)
2137  {
2138      return mParameters.getRelatedCamSyncInfo();
2139  }
2140  
2141  /*===========================================================================
2142   * FUNCTION   : setRelatedCamSyncInfo
2143   *
2144   * DESCRIPTION:sets the related cam sync info for this HWI instance
2145   *
2146   * PARAMETERS :
2147   *   @info  : ptr to related cam info parameters
2148   *
2149   * RETURN     : int32_t type of status
2150   *              NO_ERROR  -- success
2151   *              none-zero failure code
2152   *==========================================================================*/
setRelatedCamSyncInfo(cam_sync_related_sensors_event_info_t * info)2153  int32_t QCamera2HardwareInterface::setRelatedCamSyncInfo(
2154          cam_sync_related_sensors_event_info_t* info)
2155  {
2156      if(info) {
2157          return mParameters.setRelatedCamSyncInfo(info);
2158      } else {
2159          return BAD_TYPE;
2160      }
2161  }
2162  
2163  /*===========================================================================
2164   * FUNCTION   : getMpoComposition
2165   *
2166   * DESCRIPTION:function to retrieve whether Mpo composition should be enabled
2167   *                    or not
2168   *
2169   * PARAMETERS :none
2170   *
2171   * RETURN     : bool indicates whether mpo composition is enabled or not
2172   *==========================================================================*/
getMpoComposition(void)2173  bool QCamera2HardwareInterface::getMpoComposition(void)
2174  {
2175      LOGH("MpoComposition:%d ", m_bMpoEnabled);
2176      return m_bMpoEnabled;
2177  }
2178  
2179  /*===========================================================================
2180   * FUNCTION   : setMpoComposition
2181   *
2182   * DESCRIPTION:set if Mpo composition should be enabled for this HWI instance
2183   *
2184   * PARAMETERS :
2185   *   @enable  : indicates whether Mpo composition enabled or not
2186   *
2187   * RETURN     : int32_t type of status
2188   *              NO_ERROR  -- success
2189   *              none-zero failure code
2190   *==========================================================================*/
setMpoComposition(bool enable)2191  int32_t QCamera2HardwareInterface::setMpoComposition(bool enable)
2192  {
2193      // By default set Mpo composition to disable
2194      m_bMpoEnabled = false;
2195  
2196      // Enable Mpo composition only if
2197      // 1) frame sync is ON between two cameras and
2198      // 2) any advanced features are not enabled (AOST features) and
2199      // 3) not in recording mode (for liveshot case)
2200      // 4) flash is not needed
2201      if ((getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) &&
2202              !mParameters.isAdvCamFeaturesEnabled() &&
2203              !mParameters.getRecordingHintValue() &&
2204              !mFlashNeeded &&
2205              !isLongshotEnabled()) {
2206          m_bMpoEnabled = enable;
2207          LOGH("MpoComposition:%d ", m_bMpoEnabled);
2208          return NO_ERROR;
2209      } else {
2210          return BAD_TYPE;
2211      }
2212  }
2213  
2214  /*===========================================================================
2215   * FUNCTION   : getRecordingHintValue
2216   *
2217   * DESCRIPTION:function to retrieve recording hint value
2218   *
2219   * PARAMETERS :none
2220   *
2221   * RETURN     : bool indicates whether recording hint is enabled or not
2222   *==========================================================================*/
getRecordingHintValue(void)2223  bool QCamera2HardwareInterface::getRecordingHintValue(void)
2224  {
2225      return mParameters.getRecordingHintValue();
2226  }
2227  
2228  /*===========================================================================
2229   * FUNCTION   : setRecordingHintValue
2230   *
2231   * DESCRIPTION:set recording hint value
2232   *
2233   * PARAMETERS :
2234   *   @enable  : video hint value
2235   *
2236   * RETURN     : int32_t type of status
2237   *              NO_ERROR  -- success
2238   *              none-zero failure code
2239   *==========================================================================*/
setRecordingHintValue(int32_t value)2240  int32_t QCamera2HardwareInterface::setRecordingHintValue(int32_t value)
2241  {
2242      return mParameters.updateRecordingHintValue(value);
2243  }
2244  
2245  /*===========================================================================
2246   * FUNCTION   : closeCamera
2247   *
2248   * DESCRIPTION: close camera
2249   *
2250   * PARAMETERS : none
2251   *
2252   * RETURN     : int32_t type of status
2253   *              NO_ERROR  -- success
2254   *              none-zero failure code
2255   *==========================================================================*/
closeCamera()2256  int QCamera2HardwareInterface::closeCamera()
2257  {
2258      int rc = NO_ERROR;
2259      int i;
2260      char value[PROPERTY_VALUE_MAX];
2261      LOGI("E");
2262      if (!mCameraOpened) {
2263          return NO_ERROR;
2264      }
2265      LOGI("[KPI Perf]: E PROFILE_CLOSE_CAMERA camera id %d",
2266               mCameraId);
2267  
2268      // set open flag to false
2269      mCameraOpened = false;
2270  
2271      // Reset Stream config info
2272      mParameters.setStreamConfigure(false, false, true);
2273  
2274      // deinit Parameters
2275      mParameters.deinit();
2276  
2277      // exit notifier
2278      m_cbNotifier.exit();
2279  
2280      // stop and deinit postprocessor
2281      waitDeferredWork(mReprocJob);
2282      // Close the JPEG session
2283      waitDeferredWork(mJpegJob);
2284      m_postprocessor.stop();
2285      deinitJpegHandle();
2286      m_postprocessor.deinit();
2287      mInitPProcJob = 0; // reset job id, so pproc can be reinited later
2288  
2289      m_thermalAdapter.deinit();
2290  
2291      // delete all channels if not already deleted
2292      for (i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
2293          if (m_channels[i] != NULL) {
2294              m_channels[i]->stop();
2295              delete m_channels[i];
2296              m_channels[i] = NULL;
2297          }
2298      }
2299  
2300      //free all pending api results here
2301      if(m_apiResultList != NULL) {
2302          api_result_list *apiResultList = m_apiResultList;
2303          api_result_list *apiResultListNext;
2304          while (apiResultList != NULL) {
2305              apiResultListNext = apiResultList->next;
2306              free(apiResultList);
2307              apiResultList = apiResultListNext;
2308          }
2309      }
2310  
2311      rc = mCameraHandle->ops->close_camera(mCameraHandle->camera_handle);
2312      mCameraHandle = NULL;
2313  
2314      //Notify display HAL that there is no active camera session
2315      //but avoid calling the same during bootup. Refer to openCamera
2316      //for more details.
2317      property_get("service.bootanim.exit", value, "0");
2318      if (atoi(value) == 1) {
2319          pthread_mutex_lock(&gCamLock);
2320          if (--gNumCameraSessions == 0) {
2321              setCameraLaunchStatus(false);
2322          }
2323          pthread_mutex_unlock(&gCamLock);
2324      }
2325  
2326      if (mExifParams.debug_params) {
2327          free(mExifParams.debug_params);
2328          mExifParams.debug_params = NULL;
2329      }
2330  
2331      if (QCameraFlash::getInstance().releaseFlashFromCamera(mCameraId) != 0) {
2332          LOGD("Failed to release flash for camera id: %d",
2333                  mCameraId);
2334      }
2335  
2336      LOGI("[KPI Perf]: X PROFILE_CLOSE_CAMERA camera id %d, rc: %d",
2337           mCameraId, rc);
2338  
2339      return rc;
2340  }
2341  
2342  #define DATA_PTR(MEM_OBJ,INDEX) MEM_OBJ->getPtr( INDEX )
2343  
2344  
2345  /*===========================================================================
2346   * FUNCTION   : getCapabilities
2347   *
2348   * DESCRIPTION: query camera capability from back-end
2349   *
2350   * PARAMETERS :
2351   *   @ops        : mm-interface ops structure
2352   *   @cam_handle  : camera handle for which we need capability
2353   *
2354   * RETURN     : ptr type of capability structure
2355   *              capability for success
2356   *              NULL for failure
2357   *==========================================================================*/
getCapabilities(mm_camera_ops_t * ops,uint32_t cam_handle)2358  cam_capability_t *QCamera2HardwareInterface::getCapabilities(mm_camera_ops_t *ops,
2359          uint32_t cam_handle)
2360  {
2361      ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_GET_CAP);
2362      int rc = NO_ERROR;
2363      QCameraHeapMemory *capabilityHeap = NULL;
2364      cam_capability_t *cap_ptr = NULL;
2365  
2366      if (ops == NULL) {
2367          LOGE("Invalid arguments");
2368          return NULL;
2369      }
2370  
2371      capabilityHeap = new QCameraHeapMemory(1);
2372      if (capabilityHeap == NULL) {
2373          LOGE("creation of capabilityHeap failed");
2374          return NULL;
2375      }
2376  
2377      /* Allocate memory for capability buffer */
2378      rc = capabilityHeap->allocate(1, sizeof(cam_capability_t));
2379      if(rc != OK) {
2380          LOGE("No memory for capability");
2381          goto allocate_failed;
2382      }
2383  
2384      /* Map memory for capability buffer */
2385      memset(DATA_PTR(capabilityHeap,0), 0, sizeof(cam_capability_t));
2386  
2387      cam_buf_map_type_list bufMapList;
2388      rc = QCameraBufferMaps::makeSingletonBufMapList(
2389              CAM_MAPPING_BUF_TYPE_CAPABILITY,
2390              0 /*stream id*/, 0 /*buffer index*/, -1 /*plane index*/,
2391              0 /*cookie*/, capabilityHeap->getFd(0), sizeof(cam_capability_t),
2392              bufMapList, capabilityHeap->getPtr(0));
2393  
2394      if (rc == NO_ERROR) {
2395          rc = ops->map_bufs(cam_handle,
2396                  &bufMapList);
2397      }
2398      if(rc < 0) {
2399          LOGE("failed to map capability buffer");
2400          goto map_failed;
2401      }
2402  
2403      /* Query Capability */
2404      rc = ops->query_capability(cam_handle);
2405      if(rc < 0) {
2406          LOGE("failed to query capability");
2407          rc = FAILED_TRANSACTION;
2408          goto query_failed;
2409      }
2410  
2411      cap_ptr = (cam_capability_t *)malloc(sizeof(cam_capability_t));
2412      if (cap_ptr == NULL) {
2413          LOGE("out of memory");
2414          rc = NO_MEMORY;
2415          goto query_failed;
2416      }
2417  
2418      memset(cap_ptr, 0, sizeof(cam_capability_t));
2419      memcpy(cap_ptr, DATA_PTR(capabilityHeap, 0), sizeof(cam_capability_t));
2420  
2421      int index;
2422      for (index = 0; index < CAM_ANALYSIS_INFO_MAX; index++) {
2423          cam_analysis_info_t *p_analysis_info = &cap_ptr->analysis_info[index];
2424          p_analysis_info->analysis_padding_info.offset_info.offset_x = 0;
2425          p_analysis_info->analysis_padding_info.offset_info.offset_y = 0;
2426      }
2427  
2428  query_failed:
2429      ops->unmap_buf(cam_handle, CAM_MAPPING_BUF_TYPE_CAPABILITY);
2430  map_failed:
2431      capabilityHeap->deallocate();
2432  allocate_failed:
2433      delete capabilityHeap;
2434  
2435      if (rc != NO_ERROR) {
2436          return NULL;
2437      } else {
2438          return cap_ptr;
2439      }
2440  }
2441  
2442  /*===========================================================================
2443   * FUNCTION   : initCapabilities
2444   *
2445   * DESCRIPTION: initialize camera capabilities in static data struct
2446   *
2447   * PARAMETERS :
2448   *   @cameraId  : camera Id
2449   *
2450   * RETURN     : int32_t type of status
2451   *              NO_ERROR  -- success
2452   *              none-zero failure code
2453   *==========================================================================*/
initCapabilities(uint32_t cameraId,mm_camera_vtbl_t * cameraHandle)2454  int QCamera2HardwareInterface::initCapabilities(uint32_t cameraId,
2455          mm_camera_vtbl_t *cameraHandle)
2456  {
2457      ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_INIT_CAP);
2458      int rc = 0;
2459      uint32_t handle = 0;
2460  
2461      rc = camera_open((uint8_t)cameraId, &cameraHandle);
2462      if (rc) {
2463          LOGE("camera_open failed. rc = %d", rc);
2464          goto open_failed;
2465      }
2466      if (!cameraHandle) {
2467          LOGE("camera_open failed. cameraHandle = %p", cameraHandle);
2468          goto open_failed;
2469      }
2470  
2471      handle = get_main_camera_handle(cameraHandle->camera_handle);
2472      gCamCapability[cameraId] = getCapabilities(cameraHandle->ops, handle);
2473      if (gCamCapability[cameraId] == NULL) {
2474          rc = FAILED_TRANSACTION;
2475          goto failed_op;
2476      }
2477  
2478      gCamCapability[cameraId]->camera_index = cameraId;
2479      if (is_dual_camera_by_idx(cameraId)) {
2480          handle = get_aux_camera_handle(cameraHandle->camera_handle);
2481          gCamCapability[cameraId]->aux_cam_cap =
2482                  getCapabilities(cameraHandle->ops, handle);
2483          if (gCamCapability[cameraId]->aux_cam_cap == NULL) {
2484              rc = FAILED_TRANSACTION;
2485              free(gCamCapability[cameraId]);
2486              goto failed_op;
2487          }
2488  
2489          // Copy the main camera capability to main_cam_cap struct
2490          gCamCapability[cameraId]->main_cam_cap =
2491                  (cam_capability_t *)malloc(sizeof(cam_capability_t));
2492          if (gCamCapability[cameraId]->main_cam_cap == NULL) {
2493              LOGE("out of memory");
2494              rc = NO_MEMORY;
2495              goto failed_op;
2496          }
2497          memcpy(gCamCapability[cameraId]->main_cam_cap, gCamCapability[cameraId],
2498                  sizeof(cam_capability_t));
2499      }
2500  failed_op:
2501      cameraHandle->ops->close_camera(cameraHandle->camera_handle);
2502      cameraHandle = NULL;
2503  open_failed:
2504      return rc;
2505  }
2506  
2507  /*===========================================================================
2508   * FUNCTION   : getCapabilities
2509   *
2510   * DESCRIPTION: query camera capabilities
2511   *
2512   * PARAMETERS :
2513   *   @cameraId  : camera Id
2514   *   @info      : camera info struct to be filled in with camera capabilities
2515   *
2516   * RETURN     : int type of status
2517   *              NO_ERROR  -- success
2518   *              none-zero failure code
2519   *==========================================================================*/
getCapabilities(uint32_t cameraId,struct camera_info * info,cam_sync_type_t * p_cam_type)2520  int QCamera2HardwareInterface::getCapabilities(uint32_t cameraId,
2521          struct camera_info *info, cam_sync_type_t *p_cam_type)
2522  {
2523      ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_GET_CAP);
2524      int rc = NO_ERROR;
2525      struct  camera_info *p_info = NULL;
2526      pthread_mutex_lock(&gCamLock);
2527      p_info = get_cam_info(cameraId, p_cam_type);
2528      p_info->device_version = CAMERA_DEVICE_API_VERSION_1_0;
2529      p_info->static_camera_characteristics = NULL;
2530      memcpy(info, p_info, sizeof (struct camera_info));
2531      pthread_mutex_unlock(&gCamLock);
2532      return rc;
2533  }
2534  
2535  /*===========================================================================
2536   * FUNCTION   : getCamHalCapabilities
2537   *
2538   * DESCRIPTION: get the HAL capabilities structure
2539   *
2540   * PARAMETERS :
2541   *   @cameraId  : camera Id
2542   *
2543   * RETURN     : capability structure of respective camera
2544   *
2545   *==========================================================================*/
getCamHalCapabilities()2546  cam_capability_t* QCamera2HardwareInterface::getCamHalCapabilities()
2547  {
2548      return gCamCapability[mCameraId];
2549  }
2550  
2551  /*===========================================================================
2552   * FUNCTION   : getBufNumForAux
2553   *
2554   * DESCRIPTION: return number of stream buffers needed for aux camera given stream type
2555   *
2556   * PARAMETERS :
2557   *   @stream_type  : type of stream
2558   *
2559   * RETURN     : number of buffers needed
2560   * NOTE     :  Based on the use cases and auxillary camera type,
2561                      we can decide buffer count
2562   *==========================================================================*/
getBufNumForAux(cam_stream_type_t stream_type)2563  uint8_t QCamera2HardwareInterface::getBufNumForAux(cam_stream_type_t stream_type)
2564  {
2565      if (!isDualCamera()) {
2566          return 0;
2567      }
2568  
2569      uint8_t bufferCnt = 1;
2570      switch (stream_type) {
2571      case CAM_STREAM_TYPE_PREVIEW:
2572      case CAM_STREAM_TYPE_VIDEO:
2573      case CAM_STREAM_TYPE_SNAPSHOT:
2574      case CAM_STREAM_TYPE_METADATA:
2575      case CAM_STREAM_TYPE_CALLBACK:
2576      case CAM_STREAM_TYPE_ANALYSIS:
2577      case CAM_STREAM_TYPE_POSTVIEW:
2578      case CAM_STREAM_TYPE_RAW:
2579      case CAM_STREAM_TYPE_OFFLINE_PROC:
2580      case CAM_STREAM_TYPE_DEFAULT:
2581      case CAM_STREAM_TYPE_MAX:
2582          //For wide & tele, we use same buffer count premary and aux streams.
2583          bufferCnt = getBufNumRequired(stream_type);
2584          break;
2585      default:
2586          break;
2587      }
2588      LOGH("Buffer Cnt for Aux Camera : %d", bufferCnt);
2589      return bufferCnt;
2590  }
2591  
2592  /*===========================================================================
2593   * FUNCTION   : getBufNumRequired
2594   *
2595   * DESCRIPTION: return number of stream buffers needed for given stream type
2596   *
2597   * PARAMETERS :
2598   *   @stream_type  : type of stream
2599   *
2600   * RETURN     : number of buffers needed
2601   *==========================================================================*/
getBufNumRequired(cam_stream_type_t stream_type)2602  uint8_t QCamera2HardwareInterface::getBufNumRequired(cam_stream_type_t stream_type)
2603  {
2604      int bufferCnt = 0;
2605      int minCaptureBuffers = mParameters.getNumOfSnapshots();
2606      char value[PROPERTY_VALUE_MAX];
2607      bool raw_yuv = false;
2608      int persist_cnt = 0;
2609      int minPrevFps, maxPrevFps;
2610  
2611      int zslQBuffers = mParameters.getZSLQueueDepth();
2612  
2613      int minCircularBufNum = mParameters.getMaxUnmatchedFramesInQueue() +
2614                              CAMERA_MIN_JPEG_ENCODING_BUFFERS;
2615  
2616      int maxStreamBuf = minCaptureBuffers + mParameters.getMaxUnmatchedFramesInQueue() +
2617                         mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2618                         mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2619                         mParameters.getNumOfExtraBuffersForImageProc() +
2620                         EXTRA_ZSL_PREVIEW_STREAM_BUF;
2621  
2622      int minUndequeCount = 0;
2623      if (!isNoDisplayMode()) {
2624          if(mPreviewWindow != NULL) {
2625              if (mPreviewWindow->get_min_undequeued_buffer_count(mPreviewWindow,&minUndequeCount)
2626                  != 0) {
2627                  LOGW("get_min_undequeued_buffer_count  failed");
2628                  //TODO: hardcoded because MIN_UNDEQUEUED_BUFFERS not defined
2629                  //minUndequeCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS;
2630                  minUndequeCount = MIN_UNDEQUEUED_BUFFERS;
2631              }
2632          } else {
2633              //preview window might not be set at this point. So, query directly
2634              //from BufferQueue implementation of gralloc buffers.
2635              //minUndequeCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS;
2636              //hardcoded because MIN_UNDEQUEUED_BUFFERS not defined. REVISIT
2637              minUndequeCount = MIN_UNDEQUEUED_BUFFERS;
2638          }
2639          if (minUndequeCount != MIN_UNDEQUEUED_BUFFERS) {
2640              // minUndequeCount from valid preview window != hardcoded MIN_UNDEQUEUED_BUFFERS
2641              // and so change the MACRO as per minUndequeCount
2642              LOGW("WARNING : minUndequeCount(%d) != hardcoded value(%d)",
2643                       minUndequeCount, MIN_UNDEQUEUED_BUFFERS);
2644          }
2645      }
2646  
2647      LOGD("minCaptureBuffers = %d zslQBuffers = %d minCircularBufNum = %d"
2648              "maxStreamBuf = %d minUndequeCount = %d",
2649              minCaptureBuffers, zslQBuffers, minCircularBufNum,
2650              maxStreamBuf, minUndequeCount);
2651      // Get buffer count for the particular stream type
2652      switch (stream_type) {
2653      case CAM_STREAM_TYPE_PREVIEW:
2654          {
2655              if (mParameters.isZSLMode()) {
2656                  // We need to add two extra streming buffers to add
2657                  // flexibility in forming matched super buf in ZSL queue.
2658                  // with number being 'zslQBuffers + minCircularBufNum'
2659                  // we see preview buffers sometimes get dropped at CPP
2660                  // and super buf is not forming in ZSL Q for long time.
2661  
2662                  bufferCnt = zslQBuffers + minCircularBufNum +
2663                          mParameters.getNumOfExtraBuffersForImageProc() +
2664                          mParameters.getNumOfExtraBuffersForPreview() +
2665                          mParameters.getNumOfExtraHDRInBufsIfNeeded();
2666                  if (isDualCamera()) {
2667                      bufferCnt += zslQBuffers;
2668                  }
2669              } else {
2670                  bufferCnt = CAMERA_MIN_STREAMING_BUFFERS +
2671                          mParameters.getMaxUnmatchedFramesInQueue() +
2672                          mParameters.getNumOfExtraBuffersForPreview();
2673              }
2674              // ISP allocates native preview buffers and so reducing same from HAL allocation
2675              if (bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS )
2676                  bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS;
2677  
2678              // Extra ZSL preview frames are not needed for HFR case.
2679              // Thumbnail will not be derived from preview for HFR live snapshot case.
2680              if ((mParameters.getRecordingHintValue() == true)
2681                      && (!mParameters.isHfrMode())) {
2682                  bufferCnt += EXTRA_ZSL_PREVIEW_STREAM_BUF;
2683              }
2684              //Adding Extra preview buffers for 60FPS usecase.
2685              mParameters.getPreviewFpsRange(&minPrevFps, &maxPrevFps);
2686              if (maxPrevFps > CAMERA_DEFAULT_FPS) {
2687                  bufferCnt += CAMERA_MIN_DISPLAY_BUFFERS;
2688              }
2689  
2690              // Add the display minUndequeCount count on top of camera requirement
2691              bufferCnt += minUndequeCount;
2692  
2693              property_get("persist.camera.preview_yuv", value, "0");
2694              persist_cnt = atoi(value);
2695              if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM)
2696                      && (bufferCnt < persist_cnt)) {
2697                  bufferCnt = persist_cnt;
2698              }
2699          }
2700          break;
2701      case CAM_STREAM_TYPE_POSTVIEW:
2702          {
2703              bufferCnt = minCaptureBuffers +
2704                          mParameters.getMaxUnmatchedFramesInQueue() +
2705                          mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2706                          mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2707                          mParameters.getNumOfExtraBuffersForImageProc();
2708  
2709              if (bufferCnt > maxStreamBuf) {
2710                  bufferCnt = maxStreamBuf;
2711              }
2712              bufferCnt += minUndequeCount;
2713          }
2714          break;
2715      case CAM_STREAM_TYPE_SNAPSHOT:
2716          {
2717              if (mParameters.isZSLMode() || mLongshotEnabled) {
2718                  if ((minCaptureBuffers == 1 || mParameters.isUbiRefocus()) &&
2719                          !mLongshotEnabled) {
2720                      // Single ZSL snapshot case
2721                      bufferCnt = zslQBuffers + CAMERA_MIN_STREAMING_BUFFERS +
2722                              mParameters.getNumOfExtraBuffersForImageProc();
2723                  } else {
2724                      // ZSL Burst or Longshot case
2725                      bufferCnt = zslQBuffers + minCircularBufNum +
2726                              mParameters.getNumOfExtraBuffersForImageProc();
2727                  }
2728                  if (getSensorType() == CAM_SENSOR_YUV && bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS) {
2729                      //ISP allocates native buffers in YUV case
2730                      bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS;
2731                  }
2732                  if (isDualCamera()) {
2733                      bufferCnt += zslQBuffers;
2734                  }
2735              } else {
2736                  bufferCnt = minCaptureBuffers +
2737                              mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2738                              mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2739                              mParameters.getNumOfExtraBuffersForImageProc();
2740  
2741                  if (bufferCnt > maxStreamBuf) {
2742                      bufferCnt = maxStreamBuf;
2743                  }
2744              }
2745          }
2746          break;
2747      case CAM_STREAM_TYPE_RAW:
2748          property_get("persist.camera.raw_yuv", value, "0");
2749          raw_yuv = atoi(value) > 0 ? true : false;
2750  
2751          if (isRdiMode() || raw_yuv || isSecureMode()) {
2752              bufferCnt = zslQBuffers + minCircularBufNum;
2753          } else if (mParameters.isZSLMode()) {
2754              bufferCnt = zslQBuffers + minCircularBufNum;
2755              if (getSensorType() == CAM_SENSOR_YUV && bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS) {
2756                  //ISP allocates native buffers in YUV case
2757                  bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS;
2758              }
2759  
2760          } else {
2761              bufferCnt = minCaptureBuffers +
2762                          mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2763                          mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2764                          mParameters.getNumOfExtraBuffersForImageProc();
2765  
2766              if (bufferCnt > maxStreamBuf) {
2767                  bufferCnt = maxStreamBuf;
2768              }
2769          }
2770  
2771          property_get("persist.camera.preview_raw", value, "0");
2772          persist_cnt = atoi(value);
2773          if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM)
2774                  && (bufferCnt < persist_cnt)) {
2775              bufferCnt = persist_cnt;
2776          }
2777          property_get("persist.camera.video_raw", value, "0");
2778          persist_cnt = atoi(value);
2779          if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM)
2780                  && (bufferCnt < persist_cnt)) {
2781              bufferCnt = persist_cnt;
2782          }
2783  
2784          break;
2785      case CAM_STREAM_TYPE_VIDEO:
2786          {
2787              if (mParameters.getBufBatchCount()) {
2788                  //Video Buffer in case of HFR or camera batching..
2789                  bufferCnt = CAMERA_MIN_CAMERA_BATCH_BUFFERS;
2790              } else if (mParameters.getVideoBatchSize()) {
2791                  //Video Buffer count only for HAL to HAL batching.
2792                  bufferCnt = (CAMERA_MIN_VIDEO_BATCH_BUFFERS
2793                          * mParameters.getVideoBatchSize());
2794                  if (bufferCnt < CAMERA_MIN_VIDEO_BUFFERS) {
2795                      bufferCnt = CAMERA_MIN_VIDEO_BUFFERS;
2796                  }
2797              } else {
2798                  // No batching enabled.
2799                  bufferCnt = CAMERA_MIN_VIDEO_BUFFERS;
2800              }
2801  
2802              bufferCnt += mParameters.getNumOfExtraBuffersForVideo();
2803              //if its 4K encoding usecase, then add extra buffer
2804              cam_dimension_t dim;
2805              mParameters.getStreamDimension(CAM_STREAM_TYPE_VIDEO, dim);
2806              if (is4k2kResolution(&dim)) {
2807                   //get additional buffer count
2808                   property_get("vidc.enc.dcvs.extra-buff-count", value, "0");
2809                   bufferCnt += atoi(value);
2810              }
2811          }
2812          break;
2813      case CAM_STREAM_TYPE_METADATA:
2814          {
2815              if (mParameters.isZSLMode()) {
2816                  // MetaData buffers should be >= (Preview buffers-minUndequeCount)
2817                  bufferCnt = zslQBuffers + minCircularBufNum +
2818                              mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2819                              mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2820                              mParameters.getNumOfExtraBuffersForImageProc() +
2821                              EXTRA_ZSL_PREVIEW_STREAM_BUF;
2822                  if (isDualCamera()) {
2823                      bufferCnt += zslQBuffers;
2824                  }
2825              } else {
2826                  bufferCnt = minCaptureBuffers +
2827                              mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2828                              mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2829                              mParameters.getMaxUnmatchedFramesInQueue() +
2830                              CAMERA_MIN_STREAMING_BUFFERS +
2831                              mParameters.getNumOfExtraBuffersForImageProc();
2832  
2833                  if (bufferCnt > zslQBuffers + minCircularBufNum) {
2834                      bufferCnt = zslQBuffers + minCircularBufNum;
2835                  }
2836              }
2837              if (CAMERA_MIN_METADATA_BUFFERS > bufferCnt) {
2838                  bufferCnt = CAMERA_MIN_METADATA_BUFFERS;
2839              }
2840          }
2841          break;
2842      case CAM_STREAM_TYPE_OFFLINE_PROC:
2843          {
2844              bufferCnt = minCaptureBuffers;
2845              // One of the ubifocus buffers is miscellaneous buffer
2846              if (mParameters.isUbiRefocus()) {
2847                  bufferCnt -= 1;
2848              }
2849              if (mLongshotEnabled) {
2850                  bufferCnt = mParameters.getLongshotStages();
2851              }
2852          }
2853          break;
2854      case CAM_STREAM_TYPE_CALLBACK:
2855          bufferCnt = CAMERA_MIN_CALLBACK_BUFFERS;
2856          break;
2857      case CAM_STREAM_TYPE_ANALYSIS:
2858      case CAM_STREAM_TYPE_DEFAULT:
2859      case CAM_STREAM_TYPE_MAX:
2860      default:
2861          bufferCnt = 0;
2862          break;
2863      }
2864  
2865      LOGH("Buffer count = %d for stream type = %d", bufferCnt, stream_type);
2866      if (CAM_MAX_NUM_BUFS_PER_STREAM < bufferCnt) {
2867          LOGW("Buffer count %d for stream type %d exceeds limit %d",
2868                   bufferCnt, stream_type, CAM_MAX_NUM_BUFS_PER_STREAM);
2869          return CAM_MAX_NUM_BUFS_PER_STREAM;
2870      }
2871  
2872      return (uint8_t)bufferCnt;
2873  }
2874  
2875  /*===========================================================================
2876   * FUNCTION   : getStreamRefCount
2877   *
2878   * DESCRIPTION: return number of instance of stream of stream type
2879   *
2880   * PARAMETERS :
2881   *   @stream_type  : type of stream
2882   *   @cam_type      : Type of camera for this stream
2883   *
2884   * RETURN     : number of stream instances
2885   * NOTE      :  Based on the use cases and auxillary camera type,
2886                       we can decide stream reference count.
2887                       For example in wide and tele use case, we duplicate all stream
2888                       streams from premary to auxillary.
2889   *==========================================================================*/
getStreamRefCount(cam_stream_type_t stream_type,uint32_t cam_type)2890  uint8_t QCamera2HardwareInterface::getStreamRefCount(cam_stream_type_t stream_type,
2891          uint32_t cam_type)
2892  {
2893      uint8_t ref_cnt = 1;
2894  
2895      if (cam_type != MM_CAMERA_DUAL_CAM) {
2896          return ref_cnt;
2897      }
2898  
2899      switch (stream_type) {
2900      case CAM_STREAM_TYPE_PREVIEW:
2901      case CAM_STREAM_TYPE_SNAPSHOT:
2902      case CAM_STREAM_TYPE_VIDEO:
2903      case CAM_STREAM_TYPE_METADATA:
2904      case CAM_STREAM_TYPE_ANALYSIS:
2905      case CAM_STREAM_TYPE_CALLBACK:
2906          if (isDualCamera()) {
2907              ref_cnt++;
2908          }
2909          break;
2910      case CAM_STREAM_TYPE_POSTVIEW:
2911      case CAM_STREAM_TYPE_RAW:
2912      case CAM_STREAM_TYPE_OFFLINE_PROC:
2913      case CAM_STREAM_TYPE_DEFAULT:
2914      case CAM_STREAM_TYPE_MAX:
2915      default:
2916          break;
2917      }
2918      return ref_cnt;
2919  }
2920  
2921  /*===========================================================================
2922   * FUNCTION   : getCamHandleForChannel
2923   *
2924   * DESCRIPTION: return actual camera handle based on use case
2925   *
2926   * PARAMETERS :
2927   *   @ch_type  : type of channel
2928   *
2929   * RETURN     : uint32_t type camera handle
2930   * NOTE :  Based on the use cases and auxillary camera type, we can decide cam handle for channel.
2931                   Incase, we want to avoid any channel for auxillary camera, we can decide here
2932   *==========================================================================*/
getCamHandleForChannel(qcamera_ch_type_enum_t ch_type)2933  uint32_t QCamera2HardwareInterface::getCamHandleForChannel(qcamera_ch_type_enum_t ch_type)
2934  {
2935      uint32_t handle = 0;
2936      if (!isDualCamera()) {
2937          return mCameraHandle->camera_handle;
2938      }
2939  
2940      /*Based on the use case, decide camera handle for channel*/
2941      switch (ch_type) {
2942      case QCAMERA_CH_TYPE_ZSL:
2943      case QCAMERA_CH_TYPE_CAPTURE:
2944      case QCAMERA_CH_TYPE_PREVIEW:
2945      case QCAMERA_CH_TYPE_VIDEO:
2946      case QCAMERA_CH_TYPE_SNAPSHOT:
2947      case QCAMERA_CH_TYPE_RAW:
2948      case QCAMERA_CH_TYPE_METADATA:
2949      case QCAMERA_CH_TYPE_ANALYSIS:
2950      case QCAMERA_CH_TYPE_CALLBACK:
2951      case QCAMERA_CH_TYPE_MAX:
2952      default:
2953          handle = mCameraHandle->camera_handle;
2954          break;
2955      case QCAMERA_CH_TYPE_REPROCESSING:
2956          if (!mParameters.isDCmAsymmetricSnapMode()) {
2957              handle = get_main_camera_handle(mCameraHandle->camera_handle);
2958          } else {
2959              /*In Asymmetric mode, we create 2 reproc channels. But
2960                       one stream is added per channel */
2961              handle = mCameraHandle->camera_handle;
2962          }
2963          break;
2964      }
2965      return handle;
2966  }
2967  
2968  /*===========================================================================
2969   * FUNCTION   : allocateStreamBuf
2970   *
2971   * DESCRIPTION: alocate stream buffers
2972   *
2973   * PARAMETERS :
2974   *   @stream_type  : type of stream
2975   *   @size         : size of buffer
2976   *   @stride       : stride of buffer
2977   *   @scanline     : scanline of buffer
2978   *   @bufferCnt    : [IN/OUT] minimum num of buffers to be allocated.
2979   *                   could be modified during allocation if more buffers needed
2980   *
2981   * RETURN     : ptr to a memory obj that holds stream buffers.
2982   *              NULL if failed
2983   *==========================================================================*/
allocateStreamBuf(cam_stream_type_t stream_type,size_t size,int stride,int scanline,uint8_t & bufferCnt)2984  QCameraMemory *QCamera2HardwareInterface::allocateStreamBuf(
2985          cam_stream_type_t stream_type, size_t size, int stride, int scanline,
2986          uint8_t &bufferCnt)
2987  {
2988      int rc = NO_ERROR;
2989      QCameraMemory *mem = NULL;
2990      bool bCachedMem = QCAMERA_ION_USE_CACHE;
2991      bool bPoolMem = false;
2992      char value[PROPERTY_VALUE_MAX];
2993      property_get("persist.camera.mem.usepool", value, "1");
2994      if (atoi(value) == 1) {
2995          bPoolMem = true;
2996      }
2997  
2998      // Allocate stream buffer memory object
2999      switch (stream_type) {
3000      case CAM_STREAM_TYPE_PREVIEW:
3001          {
3002              if (isNoDisplayMode()) {
3003                  mem = new QCameraStreamMemory(mGetMemory,
3004                          mCallbackCookie,
3005                          bCachedMem,
3006                          (bPoolMem) ? &m_memoryPool : NULL,
3007                          stream_type);
3008              } else {
3009                  cam_dimension_t dim;
3010                  int minFPS, maxFPS;
3011                  QCameraGrallocMemory *grallocMemory = NULL;
3012  
3013                  if (isSecureMode()) {
3014                      grallocMemory = new QCameraGrallocMemory(mGetMemory, mCallbackCookie, QCAMERA_MEM_TYPE_SECURE);
3015                  }else {
3016                      grallocMemory = new QCameraGrallocMemory(mGetMemory, mCallbackCookie);
3017                  }
3018  
3019                  mParameters.getStreamDimension(stream_type, dim);
3020                  /* we are interested only in maxfps here */
3021                  mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
3022                  int usage = 0;
3023                  if(mParameters.isUBWCEnabled()) {
3024                      cam_format_t fmt;
3025                      mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW,fmt);
3026                      if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
3027                          usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC ;
3028                      }
3029                  }
3030                  if (grallocMemory) {
3031                      grallocMemory->setMappable(
3032                              CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS);
3033                      grallocMemory->setWindowInfo(mPreviewWindow,
3034                              dim.width,dim.height, stride, scanline,
3035                              mParameters.getPreviewHalPixelFormat(),
3036                              maxFPS, usage);
3037                      pthread_mutex_lock(&mGrallocLock);
3038                      if (bufferCnt > CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS) {
3039                          mEnqueuedBuffers = (bufferCnt -
3040                                  CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS);
3041                      } else {
3042                          mEnqueuedBuffers = 0;
3043                      }
3044                      pthread_mutex_unlock(&mGrallocLock);
3045                  }
3046                  mem = grallocMemory;
3047              }
3048          }
3049          break;
3050      case CAM_STREAM_TYPE_POSTVIEW:
3051          {
3052              if (isNoDisplayMode() || isPreviewRestartEnabled()) {
3053                  mem = new QCameraStreamMemory(mGetMemory, mCallbackCookie, bCachedMem);
3054              } else {
3055                  cam_dimension_t dim;
3056                  int minFPS, maxFPS;
3057                  QCameraGrallocMemory *grallocMemory =
3058                          new QCameraGrallocMemory(mGetMemory, mCallbackCookie);
3059  
3060                  mParameters.getStreamDimension(stream_type, dim);
3061                  /* we are interested only in maxfps here */
3062                  mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
3063                  if (grallocMemory) {
3064                      grallocMemory->setWindowInfo(mPreviewWindow, dim.width,
3065                              dim.height, stride, scanline,
3066                              mParameters.getPreviewHalPixelFormat(), maxFPS);
3067                  }
3068                  mem = grallocMemory;
3069              }
3070          }
3071          break;
3072      case CAM_STREAM_TYPE_ANALYSIS:
3073      case CAM_STREAM_TYPE_SNAPSHOT:
3074      case CAM_STREAM_TYPE_OFFLINE_PROC:
3075          mem = new QCameraStreamMemory(mGetMemory,
3076                  mCallbackCookie,
3077                  bCachedMem,
3078                  (bPoolMem) ? &m_memoryPool : NULL,
3079                  stream_type);
3080          break;
3081      case CAM_STREAM_TYPE_RAW:
3082          if(isSecureMode()) {
3083              mem = new QCameraStreamMemory(mGetMemory,
3084                      mCallbackCookie,
3085                      bCachedMem,
3086                      (bPoolMem) ? &m_memoryPool : NULL,
3087                      stream_type,
3088                      QCAMERA_MEM_TYPE_SECURE);
3089              LOGH("Allocating %d secure buffers of size %d ", bufferCnt, size);
3090          } else {
3091              mem = new QCameraStreamMemory(mGetMemory,
3092                      mCallbackCookie,
3093                      bCachedMem,
3094                      (bPoolMem) ? &m_memoryPool : NULL,
3095                      stream_type);
3096          }
3097          break;
3098      case CAM_STREAM_TYPE_METADATA:
3099          {
3100              if (mMetadataMem == NULL) {
3101                  mem = new QCameraMetadataStreamMemory(QCAMERA_ION_USE_CACHE);
3102              } else {
3103                  mem = mMetadataMem;
3104                  mMetadataMem = NULL;
3105  
3106                  int32_t numAdditionalBuffers = bufferCnt - mem->getCnt();
3107                  if (numAdditionalBuffers > 0) {
3108                      rc = mem->allocateMore(numAdditionalBuffers, size);
3109                      if (rc != NO_ERROR) {
3110                          LOGE("Failed to allocate additional buffers, "
3111                                  "but attempting to proceed.");
3112                      }
3113                  }
3114                  bufferCnt = mem->getCnt();
3115                  // The memory is already allocated  and initialized, so
3116                  // simply return here.
3117                  return mem;
3118              }
3119          }
3120          break;
3121      case CAM_STREAM_TYPE_VIDEO:
3122          {
3123              //Use uncached allocation by default
3124              if (mParameters.isVideoBuffersCached() || mParameters.isSeeMoreEnabled() ||
3125                      mParameters.isHighQualityNoiseReductionMode()) {
3126                  bCachedMem = QCAMERA_ION_USE_CACHE;
3127              }
3128              else {
3129                  bCachedMem = QCAMERA_ION_USE_NOCACHE;
3130              }
3131  
3132              QCameraVideoMemory *videoMemory = NULL;
3133              int usage = 0;
3134              cam_format_t fmt;
3135  
3136              if (mParameters.getVideoBatchSize()) {
3137                  videoMemory = new QCameraVideoMemory(
3138                          mGetMemory, mCallbackCookie, FALSE, QCAMERA_MEM_TYPE_BATCH);
3139                  if (videoMemory == NULL) {
3140                      LOGE("Out of memory for video batching obj");
3141                      return NULL;
3142                  }
3143                  mParameters.getStreamFormat(CAM_STREAM_TYPE_VIDEO,fmt);
3144                  if (mParameters.isUBWCEnabled() &&
3145                          (fmt == CAM_FORMAT_YUV_420_NV12_UBWC)) {
3146                      usage = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
3147                  }
3148                  videoMemory->setVideoInfo(usage, fmt);
3149                  /*
3150                  *   numFDs = BATCH size
3151                  *  numInts = 5  // OFFSET, SIZE, USAGE, TIMESTAMP, FORMAT
3152                  */
3153                  rc = videoMemory->allocateMeta(
3154                          CAMERA_MIN_VIDEO_BATCH_BUFFERS,
3155                          mParameters.getVideoBatchSize());
3156                  if (rc < 0) {
3157                      delete videoMemory;
3158                      return NULL;
3159                  }
3160              } else {
3161                  videoMemory =
3162                          new QCameraVideoMemory(mGetMemory, mCallbackCookie, bCachedMem);
3163                  if (videoMemory == NULL) {
3164                      LOGE("Out of memory for video obj");
3165                      return NULL;
3166                  }
3167                  mParameters.getStreamFormat(CAM_STREAM_TYPE_VIDEO,fmt);
3168                  if (mParameters.isUBWCEnabled() &&
3169                          (fmt == CAM_FORMAT_YUV_420_NV12_UBWC)) {
3170                      usage = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
3171                  }
3172                  videoMemory->setVideoInfo(usage, fmt);
3173              }
3174              mem = videoMemory;
3175          }
3176          break;
3177      case CAM_STREAM_TYPE_CALLBACK:
3178          mem = new QCameraStreamMemory(mGetMemory,
3179                  mCallbackCookie,
3180                  bCachedMem,
3181                  (bPoolMem) ? &m_memoryPool : NULL,
3182                  stream_type);
3183          break;
3184      case CAM_STREAM_TYPE_DEFAULT:
3185      case CAM_STREAM_TYPE_MAX:
3186      default:
3187          break;
3188      }
3189      if (!mem) {
3190          return NULL;
3191      }
3192  
3193      if (bufferCnt > 0) {
3194          rc = mem->allocate(bufferCnt, size);
3195          if (rc < 0) {
3196              delete mem;
3197              return NULL;
3198          }
3199          bufferCnt = mem->getCnt();
3200      }
3201      LOGH("rc = %d type = %d count = %d size = %d cache = %d, pool = %d mEnqueuedBuffers = %d",
3202              rc, stream_type, bufferCnt, size, bCachedMem, bPoolMem, mEnqueuedBuffers);
3203      return mem;
3204  }
3205  
3206  /*===========================================================================
3207   * FUNCTION   : allocateMoreStreamBuf
3208   *
3209   * DESCRIPTION: alocate more stream buffers from the memory object
3210   *
3211   * PARAMETERS :
3212   *   @mem_obj      : memory object ptr
3213   *   @size         : size of buffer
3214   *   @bufferCnt    : [IN/OUT] additional number of buffers to be allocated.
3215   *                   output will be the number of total buffers
3216   *
3217   * RETURN     : int32_t type of status
3218   *              NO_ERROR  -- success
3219   *              none-zero failure code
3220   *==========================================================================*/
allocateMoreStreamBuf(QCameraMemory * mem_obj,size_t size,uint8_t & bufferCnt)3221  int32_t QCamera2HardwareInterface::allocateMoreStreamBuf(
3222          QCameraMemory *mem_obj, size_t size, uint8_t &bufferCnt)
3223  {
3224      int rc = NO_ERROR;
3225  
3226      if (bufferCnt > 0) {
3227          rc = mem_obj->allocateMore(bufferCnt, size);
3228          bufferCnt = mem_obj->getCnt();
3229      }
3230      return rc;
3231  }
3232  
3233  /*===========================================================================
3234   * FUNCTION   : allocateMiscBuf
3235   *
3236   * DESCRIPTION: alocate miscellaneous buffer
3237   *
3238   * PARAMETERS :
3239   *   @streamInfo  : stream info
3240   *
3241   * RETURN     : ptr to a memory obj that holds stream info buffer.
3242   *              NULL if failed
3243   *==========================================================================*/
allocateMiscBuf(cam_stream_info_t * streamInfo)3244  QCameraHeapMemory *QCamera2HardwareInterface::allocateMiscBuf(
3245          cam_stream_info_t *streamInfo)
3246  {
3247      int rc = NO_ERROR;
3248      uint8_t bufNum = 0;
3249      size_t bufSize = 0;
3250      QCameraHeapMemory *miscBuf = NULL;
3251      cam_feature_mask_t feature_mask =
3252              streamInfo->reprocess_config.pp_feature_config.feature_mask;
3253  
3254      switch (streamInfo->stream_type) {
3255      case CAM_STREAM_TYPE_OFFLINE_PROC:
3256          if (CAM_QCOM_FEATURE_TRUEPORTRAIT & feature_mask) {
3257              bufNum = 1;
3258              bufSize = mParameters.getTPMaxMetaSize();
3259          } else if (CAM_QCOM_FEATURE_REFOCUS & feature_mask) {
3260              bufNum = 1;
3261              bufSize = mParameters.getRefocusMaxMetaSize();
3262          }
3263          break;
3264      default:
3265          break;
3266      }
3267  
3268      if (bufNum && bufSize) {
3269          miscBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
3270  
3271          if (!miscBuf) {
3272              LOGE("Unable to allocate miscBuf object");
3273              return NULL;
3274          }
3275  
3276          rc = miscBuf->allocate(bufNum, bufSize);
3277          if (rc < 0) {
3278              LOGE("Failed to allocate misc buffer memory");
3279              delete miscBuf;
3280              return NULL;
3281          }
3282      }
3283  
3284      return miscBuf;
3285  }
3286  
3287  /*===========================================================================
3288   * FUNCTION   : initStreamInfoBuf
3289   *
3290   * DESCRIPTION: initialize stream info buffer based on stream type
3291   *
3292   * PARAMETERS :
3293   *   @stream_type  : type of stream
3294   *   @cam_type      : Camera type in case of dual camera
3295   *
3296   * RETURN     : ptr to a memory obj that holds stream info buffer.
3297   *              NULL if failed
3298   *==========================================================================*/
initStreamInfoBuf(cam_stream_type_t stream_type,cam_stream_info_t * streamInfo,uint32_t cam_type)3299  int QCamera2HardwareInterface::initStreamInfoBuf(cam_stream_type_t stream_type,
3300              cam_stream_info_t *streamInfo, uint32_t cam_type)
3301  {
3302      int rc = NO_ERROR;
3303      int32_t dt = 0;
3304      int32_t vc = 0;
3305  
3306      memset(streamInfo, 0, sizeof(cam_stream_info_t));
3307      streamInfo->stream_type = stream_type;
3308      rc = mParameters.getStreamFormat(stream_type, streamInfo->fmt);
3309      rc = mParameters.getStreamDimension(stream_type, streamInfo->dim, cam_type);
3310      rc = mParameters.getStreamRotation(stream_type, streamInfo->pp_config, streamInfo->dim);
3311      streamInfo->num_bufs = getBufNumRequired(stream_type);
3312      streamInfo->buf_cnt = streamInfo->num_bufs;
3313      streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
3314      streamInfo->is_secure = NON_SECURE;
3315      // Initialize cache ops
3316      if (!m_bOptimizeCacheOps) {
3317          streamInfo->cache_ops = CAM_STREAM_CACHE_OPS_DISABLED;
3318      } else {
3319          streamInfo->cache_ops = CAM_STREAM_CACHE_OPS_HONOUR_FLAGS;
3320      }
3321  
3322      switch (stream_type) {
3323      case CAM_STREAM_TYPE_SNAPSHOT:
3324          if ((mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) ||
3325              mLongshotEnabled) {
3326              streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
3327          } else {
3328              streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
3329              streamInfo->num_of_burst = (uint8_t)
3330                      (mParameters.getNumOfSnapshots()
3331                          + mParameters.getNumOfExtraHDRInBufsIfNeeded()
3332                          - mParameters.getNumOfExtraHDROutBufsIfNeeded()
3333                          + mParameters.getNumOfExtraBuffersForImageProc());
3334          }
3335          break;
3336      case CAM_STREAM_TYPE_RAW: {
3337              char value[PROPERTY_VALUE_MAX];
3338              bool raw_yuv = false;
3339              property_get("persist.camera.raw_yuv", value, "0");
3340              raw_yuv = atoi(value) > 0 ? true : false;
3341              if ((mParameters.isZSLMode()) || (isRdiMode()) || (raw_yuv) || isSecureMode()) {
3342                  streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
3343              } else {
3344                  streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
3345                  streamInfo->num_of_burst = mParameters.getNumOfSnapshots();
3346              }
3347              if (isSecureMode()) {
3348                  streamInfo->is_secure = SECURE;
3349              } else {
3350                  streamInfo->is_secure = NON_SECURE;
3351              }
3352          }
3353          if (CAM_FORMAT_META_RAW_10BIT == streamInfo->fmt) {
3354              mParameters.updateDtVc(&dt, &vc);
3355              if (dt)
3356                  streamInfo->dt = dt;
3357              streamInfo->vc = vc;
3358          }
3359  
3360          break;
3361      case CAM_STREAM_TYPE_POSTVIEW:
3362          if (mLongshotEnabled) {
3363              streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
3364          } else {
3365              streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
3366              streamInfo->num_of_burst = (uint8_t)(mParameters.getNumOfSnapshots()
3367                  + mParameters.getNumOfExtraHDRInBufsIfNeeded()
3368                  - mParameters.getNumOfExtraHDROutBufsIfNeeded()
3369                  + mParameters.getNumOfExtraBuffersForImageProc());
3370          }
3371          break;
3372      case CAM_STREAM_TYPE_VIDEO:
3373          streamInfo->dis_enable = mParameters.isDISEnabled();
3374          if (mParameters.getBufBatchCount()) {
3375              //Update stream info structure with batch mode info
3376              streamInfo->streaming_mode = CAM_STREAMING_MODE_BATCH;
3377              streamInfo->user_buf_info.frame_buf_cnt = mParameters.getBufBatchCount();
3378              streamInfo->user_buf_info.size =
3379                      (uint32_t)(sizeof(struct msm_camera_user_buf_cont_t));
3380              cam_fps_range_t pFpsRange;
3381              mParameters.getHfrFps(pFpsRange);
3382              streamInfo->user_buf_info.frameInterval =
3383                      (long)((1000/pFpsRange.video_max_fps) * 1000);
3384              LOGH("Video Batch Count = %d, interval = %d",
3385                      streamInfo->user_buf_info.frame_buf_cnt,
3386                      streamInfo->user_buf_info.frameInterval);
3387          }
3388          if (mParameters.getRecordingHintValue()) {
3389              if(mParameters.isDISEnabled()) {
3390                  streamInfo->is_type = mParameters.getVideoISType();
3391              } else {
3392                  streamInfo->is_type = IS_TYPE_NONE;
3393              }
3394          }
3395          if (mParameters.isSecureMode()) {
3396              streamInfo->is_secure = SECURE;
3397          }
3398          break;
3399      case CAM_STREAM_TYPE_PREVIEW:
3400          if (mParameters.getRecordingHintValue()) {
3401              if(mParameters.isDISEnabled()) {
3402                  streamInfo->is_type = mParameters.getPreviewISType();
3403              } else {
3404                  streamInfo->is_type = IS_TYPE_NONE;
3405              }
3406          }
3407          if (isSecureMode()) {
3408              streamInfo->is_secure = SECURE;
3409          } else {
3410              streamInfo->is_secure = NON_SECURE;
3411          }
3412          // If SAT enabled, don't add preview stream to Bundled queue
3413          if (isDualCamera()) {
3414              char prop[PROPERTY_VALUE_MAX];
3415              memset(prop, 0, sizeof(prop));
3416              bool satEnabledFlag = FALSE;
3417              property_get("persist.camera.sat.enable", prop, "0");
3418              satEnabledFlag = atoi(prop);
3419              if (satEnabledFlag) {
3420                  streamInfo->noFrameExpected = 1;
3421              }
3422          }
3423          break;
3424      case CAM_STREAM_TYPE_ANALYSIS:
3425          streamInfo->noFrameExpected = 1;
3426          break;
3427      case CAM_STREAM_TYPE_METADATA:
3428          streamInfo->cache_ops = CAM_STREAM_CACHE_OPS_CLEAR_FLAGS;
3429          break;
3430      default:
3431          break;
3432      }
3433  
3434      // Update feature mask
3435      mParameters.updatePpFeatureMask(stream_type);
3436  
3437      // Get feature mask
3438      mParameters.getStreamPpMask(stream_type, streamInfo->pp_config.feature_mask);
3439  
3440      // Update pp config
3441      if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_FLIP) {
3442          int flipMode = mParameters.getFlipMode(stream_type);
3443          if (flipMode > 0) {
3444              streamInfo->pp_config.flip = (uint32_t)flipMode;
3445          }
3446      }
3447      if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_SHARPNESS) {
3448          streamInfo->pp_config.sharpness = mParameters.getSharpness();
3449      }
3450      if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_EFFECT) {
3451          streamInfo->pp_config.effect = mParameters.getEffectValue();
3452      }
3453  
3454      if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_DENOISE2D) {
3455          streamInfo->pp_config.denoise2d.denoise_enable = 1;
3456          streamInfo->pp_config.denoise2d.process_plates =
3457                  mParameters.getDenoiseProcessPlate(CAM_INTF_PARM_WAVELET_DENOISE);
3458      }
3459  
3460      if (!((needReprocess()) && (CAM_STREAM_TYPE_SNAPSHOT == stream_type ||
3461              CAM_STREAM_TYPE_RAW == stream_type))) {
3462          if (gCamCapability[mCameraId]->qcom_supported_feature_mask &
3463                  CAM_QCOM_FEATURE_CROP)
3464              streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
3465          if (gCamCapability[mCameraId]->qcom_supported_feature_mask &
3466                  CAM_QCOM_FEATURE_SCALE)
3467              streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
3468      }
3469      streamInfo->aux_str_info = NULL;
3470  
3471      LOGH("type %d, fmt %d, dim %dx%d, num_bufs %d mask = 0x%x is_type %d\n",
3472             stream_type, streamInfo->fmt, streamInfo->dim.width,
3473             streamInfo->dim.height, streamInfo->num_bufs,
3474             streamInfo->pp_config.feature_mask,
3475             streamInfo->is_type);
3476  
3477      return rc;
3478  }
3479  
3480  /*===========================================================================
3481   * FUNCTION   : allocateStreamInfoBuf
3482   *
3483   * DESCRIPTION: alocate stream info buffer
3484   *
3485   * PARAMETERS :
3486   *   @stream_type  : type of stream
3487   *   @bufCount       : stream info buffer count
3488   *   @cam_type     : Camera type in case of dual camera
3489   *
3490   * RETURN     : ptr to a memory obj that holds stream info buffer.
3491   *              NULL if failed
3492   *==========================================================================*/
allocateStreamInfoBuf(cam_stream_type_t stream_type,uint8_t bufCount,uint32_t cam_type)3493  QCameraHeapMemory *QCamera2HardwareInterface::allocateStreamInfoBuf(
3494          cam_stream_type_t stream_type, uint8_t bufCount, uint32_t cam_type)
3495  {
3496      int rc = NO_ERROR;
3497  
3498      QCameraHeapMemory *streamInfoBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
3499      if (!streamInfoBuf) {
3500          LOGE("allocateStreamInfoBuf: Unable to allocate streamInfo object");
3501          return NULL;
3502      }
3503  
3504      if (bufCount > MM_CAMERA_MAX_CAM_CNT) {
3505          LOGE("buffer count should be lesser than max camera : %d", bufCount);
3506          return NULL;
3507      }
3508      rc = streamInfoBuf->allocate(bufCount, sizeof(cam_stream_info_t));
3509      if (rc < 0) {
3510          LOGE("allocateStreamInfoBuf: Failed to allocate stream info memory");
3511          delete streamInfoBuf;
3512          return NULL;
3513      }
3514  
3515      for (uint8_t i = 0; i < bufCount; i++) {
3516          cam_stream_info_t *streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(i);
3517          memset(streamInfo, 0, sizeof(cam_stream_info_t));
3518          rc = initStreamInfoBuf(stream_type, streamInfo, cam_type);
3519          if (rc < 0) {
3520              LOGE("initStreamInfoBuf failed");
3521              delete streamInfoBuf;
3522              return NULL;
3523          }
3524      }
3525  
3526      cam_stream_info_t *streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(0);
3527      if (bufCount == MM_CAMERA_MAX_CAM_CNT) {
3528          cam_stream_info_t *s_streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(1);
3529          streamInfo->aux_str_info = s_streamInfo;
3530      }
3531  
3532      if (streamInfo->aux_str_info != NULL) {
3533          /*Update StreamInfo for Aux camera*/
3534          streamInfo->aux_str_info->buf_cnt = getBufNumForAux(stream_type);
3535          streamInfo->num_bufs += streamInfo->aux_str_info->buf_cnt;
3536          streamInfo->aux_str_info->num_bufs += streamInfo->aux_str_info->buf_cnt;
3537      }
3538      return streamInfoBuf;
3539  }
3540  
3541  /*===========================================================================
3542   * FUNCTION   : allocateStreamUserBuf
3543   *
3544   * DESCRIPTION: allocate user ptr for stream buffers
3545   *
3546   * PARAMETERS :
3547   *   @streamInfo  : stream info structure
3548   *
3549   * RETURN     : ptr to a memory obj that holds stream info buffer.
3550   *                    NULL if failed
3551  
3552   *==========================================================================*/
allocateStreamUserBuf(cam_stream_info_t * streamInfo)3553  QCameraMemory *QCamera2HardwareInterface::allocateStreamUserBuf(
3554          cam_stream_info_t *streamInfo)
3555  {
3556      int rc = NO_ERROR;
3557      QCameraMemory *mem = NULL;
3558      int size = 0;
3559  
3560      if (streamInfo->streaming_mode != CAM_STREAMING_MODE_BATCH) {
3561          LOGE("Stream is not in BATCH mode. Invalid Stream");
3562          return NULL;
3563      }
3564  
3565      // Allocate stream user buffer memory object
3566      switch (streamInfo->stream_type) {
3567      case CAM_STREAM_TYPE_VIDEO: {
3568          QCameraVideoMemory *video_mem = new QCameraVideoMemory(
3569                  mGetMemory, mCallbackCookie, FALSE, QCAMERA_MEM_TYPE_BATCH);
3570          if (video_mem == NULL) {
3571              LOGE("Out of memory for video obj");
3572              return NULL;
3573          }
3574  
3575          int usage = 0;
3576          cam_format_t fmt;
3577          mParameters.getStreamFormat(CAM_STREAM_TYPE_VIDEO, fmt);
3578          if(mParameters.isUBWCEnabled() && (fmt == CAM_FORMAT_YUV_420_NV12_UBWC)) {
3579              usage = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
3580          }
3581          video_mem->setVideoInfo(usage, fmt);
3582  
3583          /*
3584          *   numFDs = BATCH size
3585          *  numInts = 5  // OFFSET, SIZE, USAGE, TIMESTAMP, FORMAT
3586          */
3587          rc = video_mem->allocateMeta(streamInfo->num_bufs,
3588                  mParameters.getBufBatchCount());
3589          if (rc < 0) {
3590              LOGE("allocateMeta failed");
3591              delete video_mem;
3592              return NULL;
3593          }
3594          mem = static_cast<QCameraMemory *>(video_mem);
3595      }
3596      break;
3597  
3598      case CAM_STREAM_TYPE_PREVIEW:
3599      case CAM_STREAM_TYPE_POSTVIEW:
3600      case CAM_STREAM_TYPE_ANALYSIS:
3601      case CAM_STREAM_TYPE_SNAPSHOT:
3602      case CAM_STREAM_TYPE_RAW:
3603      case CAM_STREAM_TYPE_METADATA:
3604      case CAM_STREAM_TYPE_OFFLINE_PROC:
3605      case CAM_STREAM_TYPE_CALLBACK:
3606          LOGE("Stream type Not supported.for BATCH processing");
3607      break;
3608  
3609      case CAM_STREAM_TYPE_DEFAULT:
3610      case CAM_STREAM_TYPE_MAX:
3611      default:
3612          break;
3613      }
3614      if (!mem) {
3615          LOGE("Failed to allocate mem");
3616          return NULL;
3617      }
3618  
3619      /*Size of this buffer will be number of batch buffer */
3620      size = PAD_TO_SIZE((streamInfo->num_bufs * streamInfo->user_buf_info.size),
3621              CAM_PAD_TO_4K);
3622  
3623      LOGH("Allocating BATCH Buffer count = %d", streamInfo->num_bufs);
3624  
3625      if (size > 0) {
3626          // Allocating one buffer for all batch buffers
3627          rc = mem->allocate(1, size);
3628          if (rc < 0) {
3629              delete mem;
3630              return NULL;
3631          }
3632      }
3633      return mem;
3634  }
3635  
3636  
3637  /*===========================================================================
3638   * FUNCTION   : waitForDeferredAlloc
3639   *
3640   * DESCRIPTION: Wait for deferred allocation, if applicable
3641   *              (applicable only for metadata buffers so far)
3642   *
3643   * PARAMETERS :
3644   *   @stream_type  : type of stream to (possibly) wait for
3645   *
3646   * RETURN     : None
3647   *==========================================================================*/
waitForDeferredAlloc(cam_stream_type_t stream_type)3648  void QCamera2HardwareInterface::waitForDeferredAlloc(cam_stream_type_t stream_type)
3649  {
3650      if (stream_type == CAM_STREAM_TYPE_METADATA) {
3651          waitDeferredWork(mMetadataAllocJob);
3652      }
3653  }
3654  
3655  
3656  /*===========================================================================
3657   * FUNCTION   : setPreviewWindow
3658   *
3659   * DESCRIPTION: set preview window impl
3660   *
3661   * PARAMETERS :
3662   *   @window  : ptr to window ops table struct
3663   *
3664   * RETURN     : int32_t type of status
3665   *              NO_ERROR  -- success
3666   *              none-zero failure code
3667   *==========================================================================*/
setPreviewWindow(struct preview_stream_ops * window)3668  int QCamera2HardwareInterface::setPreviewWindow(
3669          struct preview_stream_ops *window)
3670  {
3671      mPreviewWindow = window;
3672      return NO_ERROR;
3673  }
3674  
3675  /*===========================================================================
3676   * FUNCTION   : setCallBacks
3677   *
3678   * DESCRIPTION: set callbacks impl
3679   *
3680   * PARAMETERS :
3681   *   @notify_cb  : notify cb
3682   *   @data_cb    : data cb
3683   *   @data_cb_timestamp : data cb with time stamp
3684   *   @get_memory : request memory ops table
3685   *   @user       : user data ptr
3686   *
3687   * RETURN     : int32_t type of status
3688   *              NO_ERROR  -- success
3689   *              none-zero failure code
3690   *==========================================================================*/
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)3691  int QCamera2HardwareInterface::setCallBacks(camera_notify_callback notify_cb,
3692                                              camera_data_callback data_cb,
3693                                              camera_data_timestamp_callback data_cb_timestamp,
3694                                              camera_request_memory get_memory,
3695                                              void *user)
3696  {
3697      mNotifyCb        = notify_cb;
3698      mDataCb          = data_cb;
3699      mDataCbTimestamp = data_cb_timestamp;
3700      mGetMemory       = get_memory;
3701      mCallbackCookie  = user;
3702      m_cbNotifier.setCallbacks(notify_cb, data_cb, data_cb_timestamp, user);
3703      return NO_ERROR;
3704  }
3705  
3706  /*===========================================================================
3707   * FUNCTION   : setJpegCallBacks
3708   *
3709   * DESCRIPTION: set JPEG callbacks impl
3710   *
3711   * PARAMETERS :
3712   *   @jpegCb  : Jpeg callback method
3713   *   @callbackCookie    : callback cookie
3714   *
3715   * RETURN     : int32_t type of status
3716   *              NO_ERROR  -- success
3717   *              none-zero failure code
3718   *==========================================================================*/
setJpegCallBacks(jpeg_data_callback jpegCb,void * callbackCookie)3719  void QCamera2HardwareInterface::setJpegCallBacks(jpeg_data_callback jpegCb,
3720                                              void *callbackCookie)
3721  {
3722      LOGH("camera id %d", getCameraId());
3723      mJpegCb        = jpegCb;
3724      mJpegCallbackCookie  = callbackCookie;
3725      m_cbNotifier.setJpegCallBacks(mJpegCb, mJpegCallbackCookie);
3726  }
3727  
3728  /*===========================================================================
3729   * FUNCTION   : enableMsgType
3730   *
3731   * DESCRIPTION: enable msg type impl
3732   *
3733   * PARAMETERS :
3734   *   @msg_type  : msg type mask to be enabled
3735   *
3736   * RETURN     : int32_t type of status
3737   *              NO_ERROR  -- success
3738   *              none-zero failure code
3739   *==========================================================================*/
enableMsgType(int32_t msg_type)3740  int QCamera2HardwareInterface::enableMsgType(int32_t msg_type)
3741  {
3742      int32_t rc = NO_ERROR;
3743  
3744      if (mParameters.isUBWCEnabled()) {
3745          /*Need Special CALLBACK stream incase application requesting for
3746                Preview callback  in UBWC case*/
3747          if (!(msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) &&
3748                  (msg_type & CAMERA_MSG_PREVIEW_FRAME)) {
3749              // Start callback channel only when preview/zsl channel is active
3750              QCameraChannel* previewCh = NULL;
3751              if (isZSLMode() && (getRecordingHintValue() != true)) {
3752                  previewCh = m_channels[QCAMERA_CH_TYPE_ZSL];
3753              } else {
3754                  previewCh = m_channels[QCAMERA_CH_TYPE_PREVIEW];
3755              }
3756              QCameraChannel* callbackCh = m_channels[QCAMERA_CH_TYPE_CALLBACK];
3757              if ((callbackCh != NULL) &&
3758                      (previewCh != NULL) && previewCh->isActive()) {
3759                  rc = startChannel(QCAMERA_CH_TYPE_CALLBACK);
3760                  if (rc != NO_ERROR) {
3761                      LOGE("START Callback Channel failed");
3762                  }
3763              }
3764          }
3765      }
3766      mMsgEnabled |= msg_type;
3767      LOGH("(0x%x) : mMsgEnabled = 0x%x rc = %d", msg_type , mMsgEnabled, rc);
3768      return rc;
3769  }
3770  
3771  /*===========================================================================
3772   * FUNCTION   : disableMsgType
3773   *
3774   * DESCRIPTION: disable msg type impl
3775   *
3776   * PARAMETERS :
3777   *   @msg_type  : msg type mask to be disabled
3778   *
3779   * RETURN     : int32_t type of status
3780   *              NO_ERROR  -- success
3781   *              none-zero failure code
3782   *==========================================================================*/
disableMsgType(int32_t msg_type)3783  int QCamera2HardwareInterface::disableMsgType(int32_t msg_type)
3784  {
3785      int32_t rc = NO_ERROR;
3786  
3787      if (mParameters.isUBWCEnabled()) {
3788          /*STOP CALLBACK STREAM*/
3789          if ((msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) &&
3790                  (msg_type & CAMERA_MSG_PREVIEW_FRAME)) {
3791              // Stop callback channel only if it is active
3792              if ((m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL) &&
3793                     (m_channels[QCAMERA_CH_TYPE_CALLBACK]->isActive())) {
3794                  rc = stopChannel(QCAMERA_CH_TYPE_CALLBACK);
3795                  if (rc != NO_ERROR) {
3796                      LOGE("STOP Callback Channel failed");
3797                  }
3798              }
3799          }
3800      }
3801      mMsgEnabled &= ~msg_type;
3802      LOGH("(0x%x) : mMsgEnabled = 0x%x rc = %d", msg_type , mMsgEnabled, rc);
3803      return rc;
3804  }
3805  
3806  /*===========================================================================
3807   * FUNCTION   : msgTypeEnabled
3808   *
3809   * DESCRIPTION: impl to determine if certain msg_type is enabled
3810   *
3811   * PARAMETERS :
3812   *   @msg_type  : msg type mask
3813   *
3814   * RETURN     : 0 -- not enabled
3815   *              none 0 -- enabled
3816   *==========================================================================*/
msgTypeEnabled(int32_t msg_type)3817  int QCamera2HardwareInterface::msgTypeEnabled(int32_t msg_type)
3818  {
3819      return (mMsgEnabled & msg_type);
3820  }
3821  
3822  /*===========================================================================
3823   * FUNCTION   : msgTypeEnabledWithLock
3824   *
3825   * DESCRIPTION: impl to determine if certain msg_type is enabled with lock
3826   *
3827   * PARAMETERS :
3828   *   @msg_type  : msg type mask
3829   *
3830   * RETURN     : 0 -- not enabled
3831   *              none 0 -- enabled
3832   *==========================================================================*/
msgTypeEnabledWithLock(int32_t msg_type)3833  int QCamera2HardwareInterface::msgTypeEnabledWithLock(int32_t msg_type)
3834  {
3835      int enabled = 0;
3836      lockAPI();
3837      enabled = mMsgEnabled & msg_type;
3838      unlockAPI();
3839      return enabled;
3840  }
3841  
3842  /*===========================================================================
3843   * FUNCTION   : startPreview
3844   *
3845   * DESCRIPTION: start preview impl
3846   *
3847   * PARAMETERS : none
3848   *
3849   * RETURN     : int32_t type of status
3850   *              NO_ERROR  -- success
3851   *              none-zero failure code
3852   *==========================================================================*/
startPreview()3853  int QCamera2HardwareInterface::startPreview()
3854  {
3855      KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_STARTPREVIEW);
3856      int32_t rc = NO_ERROR;
3857  
3858      LOGI("E ZSL = %d Recording Hint = %d", mParameters.isZSLMode(),
3859              mParameters.getRecordingHintValue());
3860  
3861      m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_START_PREVIEW);
3862  
3863      updateThermalLevel((void *)&mThermalLevel);
3864  
3865      setDisplayFrameSkip();
3866  
3867      // start preview stream
3868      if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) {
3869          rc = startChannel(QCAMERA_CH_TYPE_ZSL);
3870      } else if (isSecureMode()) {
3871          if (mParameters.getSecureStreamType() == CAM_STREAM_TYPE_RAW) {
3872              rc = startChannel(QCAMERA_CH_TYPE_RAW);
3873          }else {
3874              rc = startChannel(QCAMERA_CH_TYPE_PREVIEW);
3875          }
3876      } else {
3877          rc = startChannel(QCAMERA_CH_TYPE_PREVIEW);
3878      }
3879  
3880      if (isDualCamera()) {
3881          if (rc == NO_ERROR) {
3882              mParameters.setDeferCamera(CAM_DEFER_PROCESS);
3883          } else {
3884              mParameters.setDeferCamera(CAM_DEFER_FLUSH);
3885          }
3886      }
3887  
3888      if (rc != NO_ERROR) {
3889          LOGE("failed to start channels");
3890          m_perfLockMgr.releasePerfLock(PERF_LOCK_START_PREVIEW);
3891          return rc;
3892      }
3893  
3894      if ((msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME))
3895              && (m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL)) {
3896          rc = startChannel(QCAMERA_CH_TYPE_CALLBACK);
3897          if (rc != NO_ERROR) {
3898              LOGE("failed to start callback stream");
3899              stopChannel(QCAMERA_CH_TYPE_ZSL);
3900              stopChannel(QCAMERA_CH_TYPE_PREVIEW);
3901              m_perfLockMgr.releasePerfLock(PERF_LOCK_START_PREVIEW);
3902              return rc;
3903          }
3904      }
3905  
3906      updatePostPreviewParameters();
3907      m_stateMachine.setPreviewCallbackNeeded(true);
3908  
3909      // if job id is non-zero, that means the postproc init job is already
3910      // pending or complete
3911      if (mInitPProcJob == 0) {
3912          mInitPProcJob = deferPPInit();
3913          if (mInitPProcJob == 0) {
3914              LOGE("Unable to initialize postprocessor, mCameraHandle = %p",
3915                       mCameraHandle);
3916              rc = -ENOMEM;
3917              m_perfLockMgr.releasePerfLock(PERF_LOCK_START_PREVIEW);
3918              return rc;
3919          }
3920      }
3921  
3922      LOGI("X rc = %d", rc);
3923      return rc;
3924  }
3925  
updatePostPreviewParameters()3926  int32_t QCamera2HardwareInterface::updatePostPreviewParameters() {
3927      // Enable OIS only in Camera mode and 4k2k camcoder mode
3928      int32_t rc = NO_ERROR;
3929      rc = mParameters.updateOisValue(1);
3930      return NO_ERROR;
3931  }
3932  
3933  /*===========================================================================
3934   * FUNCTION   : stopPreview
3935   *
3936   * DESCRIPTION: stop preview impl
3937   *
3938   * PARAMETERS : none
3939   *
3940   * RETURN     : int32_t type of status
3941   *              NO_ERROR  -- success
3942   *              none-zero failure code
3943   *==========================================================================*/
stopPreview()3944  int QCamera2HardwareInterface::stopPreview()
3945  {
3946      KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_STOPPREVIEW);
3947      LOGI("E");
3948      mNumPreviewFaces = -1;
3949      mActiveAF = false;
3950  
3951      // Disable power Hint for preview
3952      m_perfLockMgr.releasePerfLock(PERF_LOCK_POWERHINT_PREVIEW);
3953  
3954      m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_STOP_PREVIEW);
3955  
3956      // stop preview stream
3957      stopChannel(QCAMERA_CH_TYPE_CALLBACK);
3958      stopChannel(QCAMERA_CH_TYPE_ZSL);
3959      stopChannel(QCAMERA_CH_TYPE_PREVIEW);
3960      stopChannel(QCAMERA_CH_TYPE_RAW);
3961  
3962      m_cbNotifier.flushPreviewNotifications();
3963      //add for ts makeup
3964  #ifdef TARGET_TS_MAKEUP
3965      ts_makeup_finish();
3966  #endif
3967      // delete all channels from preparePreview
3968      unpreparePreview();
3969  
3970      m_perfLockMgr.releasePerfLock(PERF_LOCK_STOP_PREVIEW);
3971      LOGI("X");
3972      return NO_ERROR;
3973  }
3974  
3975  /*===========================================================================
3976   * FUNCTION   : storeMetaDataInBuffers
3977   *
3978   * DESCRIPTION: enable store meta data in buffers for video frames impl
3979   *
3980   * PARAMETERS :
3981   *   @enable  : flag if need enable
3982   *
3983   * RETURN     : int32_t type of status
3984   *              NO_ERROR  -- success
3985   *              none-zero failure code
3986   *==========================================================================*/
storeMetaDataInBuffers(int enable)3987  int QCamera2HardwareInterface::storeMetaDataInBuffers(int enable)
3988  {
3989      mStoreMetaDataInFrame = enable;
3990      return NO_ERROR;
3991  }
3992  
3993  /*===========================================================================
3994   * FUNCTION   : preStartRecording
3995   *
3996   * DESCRIPTION: Prepare start recording impl
3997   *
3998   * PARAMETERS : none
3999   *
4000   * RETURN     : int32_t type of status
4001   *              NO_ERROR  -- success
4002   *              none-zero failure code
4003   *==========================================================================*/
preStartRecording()4004  int QCamera2HardwareInterface::preStartRecording()
4005  {
4006      int32_t rc = NO_ERROR;
4007      LOGH("E");
4008      if (mParameters.getRecordingHintValue() == false) {
4009  
4010          // Give HWI control to restart preview only in single camera mode.
4011          // In dual-cam mode, this control belongs to muxer.
4012          if (getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
4013              LOGH("start recording when hint is false, stop preview first");
4014              stopPreview();
4015  
4016              // Set recording hint to TRUE
4017              mParameters.updateRecordingHintValue(TRUE);
4018              rc = preparePreview();
4019              if (rc == NO_ERROR) {
4020                  rc = startPreview();
4021              }
4022          }
4023          else
4024          {
4025              // For dual cam mode, update the flag mPreviewRestartNeeded to true
4026              // Restart control will be handled by muxer.
4027              mPreviewRestartNeeded = true;
4028          }
4029      }
4030  
4031      LOGH("X rc = %d", rc);
4032      return rc;
4033  }
4034  
4035  /*===========================================================================
4036   * FUNCTION   : startRecording
4037   *
4038   * DESCRIPTION: start recording impl
4039   *
4040   * PARAMETERS : none
4041   *
4042   * RETURN     : int32_t type of status
4043   *              NO_ERROR  -- success
4044   *              none-zero failure code
4045   *==========================================================================*/
startRecording()4046  int QCamera2HardwareInterface::startRecording()
4047  {
4048      int32_t rc = NO_ERROR;
4049  
4050      LOGI("E");
4051  
4052      m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_START_RECORDING);
4053  
4054      //link meta stream with video channel if low power mode.
4055      if (isLowPowerMode()) {
4056          // Find and try to link a metadata stream from preview channel
4057          QCameraChannel *pMetaChannel = NULL;
4058          QCameraStream *pMetaStream = NULL;
4059          QCameraChannel *pVideoChannel = m_channels[QCAMERA_CH_TYPE_VIDEO];
4060  
4061          if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
4062              pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
4063              uint32_t streamNum = pMetaChannel->getNumOfStreams();
4064              QCameraStream *pStream = NULL;
4065              for (uint32_t i = 0 ; i < streamNum ; i++ ) {
4066                  pStream = pMetaChannel->getStreamByIndex(i);
4067                  if ((NULL != pStream) &&
4068                          (CAM_STREAM_TYPE_METADATA == pStream->getMyType())) {
4069                      pMetaStream = pStream;
4070                      break;
4071                  }
4072              }
4073          }
4074  
4075          if ((NULL != pMetaChannel) && (NULL != pMetaStream)) {
4076              rc = pVideoChannel->linkStream(pMetaChannel, pMetaStream);
4077              if (NO_ERROR != rc) {
4078                  LOGW("Metadata stream link failed %d", rc);
4079              }
4080          }
4081      }
4082  
4083      if (rc == NO_ERROR) {
4084          rc = startChannel(QCAMERA_CH_TYPE_VIDEO);
4085      }
4086  
4087      if (mParameters.isTNRSnapshotEnabled() && !isLowPowerMode()) {
4088          QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
4089          if (!mParameters.is4k2kVideoResolution()) {
4090              // Find and try to link a metadata stream from preview channel
4091              QCameraChannel *pMetaChannel = NULL;
4092              QCameraStream *pMetaStream = NULL;
4093  
4094              if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
4095                  pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
4096                  uint32_t streamNum = pMetaChannel->getNumOfStreams();
4097                  QCameraStream *pStream = NULL;
4098                  for (uint32_t i = 0 ; i < streamNum ; i++ ) {
4099                      pStream = pMetaChannel->getStreamByIndex(i);
4100                      if ((NULL != pStream) &&
4101                              (CAM_STREAM_TYPE_METADATA ==
4102                              pStream->getMyType())) {
4103                          pMetaStream = pStream;
4104                          break;
4105                      }
4106                  }
4107              }
4108  
4109              if ((NULL != pMetaChannel) && (NULL != pMetaStream)) {
4110                  rc = pChannel->linkStream(pMetaChannel, pMetaStream);
4111                  if (NO_ERROR != rc) {
4112                      LOGW("Metadata stream link failed %d", rc);
4113                  }
4114              }
4115          }
4116          LOGH("START snapshot Channel for TNR processing");
4117          rc = pChannel->start();
4118      }
4119  
4120      m_perfLockMgr.releasePerfLock(PERF_LOCK_START_RECORDING);
4121  
4122      if (rc == NO_ERROR) {
4123          // Set power Hint for video encoding
4124          m_perfLockMgr.acquirePerfLock(PERF_LOCK_POWERHINT_ENCODE, 0);
4125      }
4126  
4127      LOGI("X rc = %d", rc);
4128      return rc;
4129  }
4130  
4131  /*===========================================================================
4132   * FUNCTION   : stopRecording
4133   *
4134   * DESCRIPTION: stop recording impl
4135   *
4136   * PARAMETERS : none
4137   *
4138   * RETURN     : int32_t type of status
4139   *              NO_ERROR  -- success
4140   *              none-zero failure code
4141   *==========================================================================*/
stopRecording()4142  int QCamera2HardwareInterface::stopRecording()
4143  {
4144      LOGI("E");
4145  
4146      // Disable power hint for video encoding
4147      m_perfLockMgr.releasePerfLock(PERF_LOCK_POWERHINT_ENCODE);
4148  
4149      m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_STOP_RECORDING);
4150  
4151      // stop snapshot channel
4152      if (mParameters.isTNRSnapshotEnabled()) {
4153          LOGH("STOP snapshot Channel for TNR processing");
4154          stopChannel(QCAMERA_CH_TYPE_SNAPSHOT);
4155      }
4156      int rc = stopChannel(QCAMERA_CH_TYPE_VIDEO);
4157  
4158      m_cbNotifier.flushVideoNotifications();
4159  
4160      m_perfLockMgr.releasePerfLock(PERF_LOCK_STOP_RECORDING);
4161  
4162      LOGI("X rc = %d", rc);
4163      return rc;
4164  }
4165  
4166  /*===========================================================================
4167   * FUNCTION   : releaseRecordingFrame
4168   *
4169   * DESCRIPTION: return video frame impl
4170   *
4171   * PARAMETERS :
4172   *   @opaque  : ptr to video frame to be returned
4173   *
4174   * RETURN     : int32_t type of status
4175   *              NO_ERROR  -- success
4176   *              none-zero failure code
4177   *==========================================================================*/
releaseRecordingFrame(const void * opaque)4178  int QCamera2HardwareInterface::releaseRecordingFrame(const void * opaque)
4179  {
4180      int32_t rc = UNKNOWN_ERROR;
4181      QCameraVideoChannel *pChannel =
4182              (QCameraVideoChannel *)m_channels[QCAMERA_CH_TYPE_VIDEO];
4183      LOGD("opaque data = %p",opaque);
4184  
4185      if(pChannel != NULL) {
4186          rc = pChannel->releaseFrame(opaque, mStoreMetaDataInFrame > 0);
4187      }
4188      return rc;
4189  }
4190  
4191  /*===========================================================================
4192   * FUNCTION   : autoFocus
4193   *
4194   * DESCRIPTION: start auto focus impl
4195   *
4196   * PARAMETERS : none
4197   *
4198   * RETURN     : int32_t type of status
4199   *              NO_ERROR  -- success
4200   *              none-zero failure code
4201   *==========================================================================*/
autoFocus()4202  int QCamera2HardwareInterface::autoFocus()
4203  {
4204      int rc = NO_ERROR;
4205      cam_focus_mode_type focusMode = mParameters.getFocusMode();
4206      LOGH("E");
4207  
4208      switch (focusMode) {
4209      case CAM_FOCUS_MODE_AUTO:
4210      case CAM_FOCUS_MODE_MACRO:
4211      case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
4212      case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
4213          mActiveAF = true;
4214          LOGI("Send AUTO FOCUS event. focusMode=%d, m_currentFocusState=%d",
4215                  focusMode, m_currentFocusState);
4216          rc = mCameraHandle->ops->do_auto_focus(mCameraHandle->camera_handle);
4217          break;
4218      case CAM_FOCUS_MODE_INFINITY:
4219      case CAM_FOCUS_MODE_FIXED:
4220      case CAM_FOCUS_MODE_EDOF:
4221      default:
4222          LOGI("No ops in focusMode (%d)", focusMode);
4223          rc = sendEvtNotify(CAMERA_MSG_FOCUS, true, 0);
4224          break;
4225      }
4226  
4227      if (NO_ERROR != rc) {
4228          mActiveAF = false;
4229      }
4230      LOGH("X rc = %d", rc);
4231      return rc;
4232  }
4233  
4234  /*===========================================================================
4235   * FUNCTION   : cancelAutoFocus
4236   *
4237   * DESCRIPTION: cancel auto focus impl
4238   *
4239   * PARAMETERS : none
4240   *
4241   * RETURN     : int32_t type of status
4242   *              NO_ERROR  -- success
4243   *              none-zero failure code
4244   *==========================================================================*/
cancelAutoFocus()4245  int QCamera2HardwareInterface::cancelAutoFocus()
4246  {
4247      int rc = NO_ERROR;
4248      cam_focus_mode_type focusMode = mParameters.getFocusMode();
4249  
4250      switch (focusMode) {
4251      case CAM_FOCUS_MODE_AUTO:
4252      case CAM_FOCUS_MODE_MACRO:
4253      case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
4254      case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
4255          mActiveAF = false;
4256          rc = mCameraHandle->ops->cancel_auto_focus(mCameraHandle->camera_handle);
4257          break;
4258      case CAM_FOCUS_MODE_INFINITY:
4259      case CAM_FOCUS_MODE_FIXED:
4260      case CAM_FOCUS_MODE_EDOF:
4261      default:
4262          LOGD("No ops in focusMode (%d)", focusMode);
4263          break;
4264      }
4265      return rc;
4266  }
4267  
4268  /*===========================================================================
4269   * FUNCTION   : processUFDumps
4270   *
4271   * DESCRIPTION: process UF jpeg dumps for refocus support
4272   *
4273   * PARAMETERS :
4274   *   @evt     : payload of jpeg event, including information about jpeg encoding
4275   *              status, jpeg size and so on.
4276   *
4277   * RETURN     : int32_t type of status
4278   *              NO_ERROR  -- success
4279   *              none-zero failure code
4280   *
4281   * NOTE       : none
4282   *==========================================================================*/
processUFDumps(qcamera_jpeg_evt_payload_t * evt)4283  bool QCamera2HardwareInterface::processUFDumps(qcamera_jpeg_evt_payload_t *evt)
4284  {
4285     bool ret = true;
4286     if (mParameters.isUbiRefocus()) {
4287         int index = (int)getOutputImageCount();
4288         bool allFocusImage = (index == ((int)mParameters.getRefocusOutputCount() - 1));
4289         char name[FILENAME_MAX];
4290  
4291         camera_memory_t *jpeg_mem = NULL;
4292         omx_jpeg_ouput_buf_t *jpeg_out = NULL;
4293         size_t dataLen;
4294         uint8_t *dataPtr;
4295         if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
4296             LOGE("Init PProc Deferred work failed");
4297             return false;
4298         }
4299         if (!m_postprocessor.getJpegMemOpt()) {
4300             dataLen = evt->out_data.buf_filled_len;
4301             dataPtr = evt->out_data.buf_vaddr;
4302         } else {
4303             jpeg_out  = (omx_jpeg_ouput_buf_t*) evt->out_data.buf_vaddr;
4304             if (!jpeg_out) {
4305                LOGE("Null pointer detected");
4306                return false;
4307             }
4308             jpeg_mem = (camera_memory_t *)jpeg_out->mem_hdl;
4309             if (!jpeg_mem) {
4310                LOGE("Null pointer detected");
4311                return false;
4312             }
4313             dataPtr = (uint8_t *)jpeg_mem->data;
4314             dataLen = jpeg_mem->size;
4315         }
4316  
4317         if (allFocusImage)  {
4318             snprintf(name, sizeof(name), "AllFocusImage");
4319             index = -1;
4320         } else {
4321             snprintf(name, sizeof(name), "%d", 0);
4322         }
4323         CAM_DUMP_TO_FILE(QCAMERA_DUMP_FRM_LOCATION"ubifocus", name, index, "jpg",
4324             dataPtr, dataLen);
4325         LOGD("Dump the image %d %d allFocusImage %d",
4326             getOutputImageCount(), index, allFocusImage);
4327         setOutputImageCount(getOutputImageCount() + 1);
4328         if (!allFocusImage) {
4329             ret = false;
4330         }
4331     }
4332     return ret;
4333  }
4334  
4335  /*===========================================================================
4336   * FUNCTION   : unconfigureAdvancedCapture
4337   *
4338   * DESCRIPTION: unconfigure Advanced Capture.
4339   *
4340   * PARAMETERS : none
4341   *
4342   * RETURN     : int32_t type of status
4343   *              NO_ERROR  -- success
4344   *              none-zero failure code
4345   *==========================================================================*/
unconfigureAdvancedCapture()4346  int32_t QCamera2HardwareInterface::unconfigureAdvancedCapture()
4347  {
4348      int32_t rc = NO_ERROR;
4349  
4350      /*Disable Quadra CFA mode*/
4351      LOGH("Disabling Quadra CFA mode");
4352      mParameters.setQuadraCfaMode(false, true);
4353  
4354      if (mAdvancedCaptureConfigured) {
4355  
4356          mAdvancedCaptureConfigured = false;
4357  
4358          if(mIs3ALocked) {
4359              mParameters.set3ALock(false);
4360              mIs3ALocked = false;
4361          }
4362          if (mParameters.isHDREnabled() || mParameters.isAEBracketEnabled()) {
4363              rc = mParameters.setToneMapMode(true, true);
4364              if (rc != NO_ERROR) {
4365                  LOGW("Failed to enable tone map during HDR/AEBracketing");
4366              }
4367              mHDRBracketingEnabled = false;
4368              rc = mParameters.stopAEBracket();
4369          } else if ((mParameters.isChromaFlashEnabled())
4370                  || (mFlashConfigured && !mLongshotEnabled)
4371                  || (mLowLightConfigured == true)
4372                  || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
4373              rc = mParameters.resetFrameCapture(TRUE, mLowLightConfigured);
4374          } else if (mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
4375              rc = configureAFBracketing(false);
4376          } else if (mParameters.isOptiZoomEnabled()) {
4377              rc = mParameters.setAndCommitZoom(mZoomLevel);
4378              setDisplaySkip(FALSE, CAMERA_MAX_PARAM_APPLY_DELAY);
4379          } else if (mParameters.isStillMoreEnabled()) {
4380              cam_still_more_t stillmore_config = mParameters.getStillMoreSettings();
4381              stillmore_config.burst_count = 0;
4382              mParameters.setStillMoreSettings(stillmore_config);
4383  
4384              /* If SeeMore is running, it will handle re-enabling tone map */
4385              if (!mParameters.isSeeMoreEnabled() && !mParameters.isLTMForSeeMoreEnabled()) {
4386                  rc = mParameters.setToneMapMode(true, true);
4387                  if (rc != NO_ERROR) {
4388                      LOGW("Failed to enable tone map during StillMore");
4389                  }
4390              }
4391  
4392              /* Re-enable Tintless */
4393              mParameters.setTintless(true);
4394          } else {
4395              LOGW("No Advanced Capture feature enabled!!");
4396              rc = BAD_VALUE;
4397          }
4398      }
4399  
4400      return rc;
4401  }
4402  
4403  /*===========================================================================
4404   * FUNCTION   : configureAdvancedCapture
4405   *
4406   * DESCRIPTION: configure Advanced Capture.
4407   *
4408   * PARAMETERS : none
4409   *
4410   * RETURN     : int32_t type of status
4411   *              NO_ERROR  -- success
4412   *              none-zero failure code
4413   *==========================================================================*/
configureAdvancedCapture()4414  int32_t QCamera2HardwareInterface::configureAdvancedCapture()
4415  {
4416      LOGH("E");
4417      int32_t rc = NO_ERROR;
4418  
4419      rc = mParameters.checkFeatureConcurrency();
4420      if (rc != NO_ERROR) {
4421          LOGE("Cannot support Advanced capture modes");
4422          return rc;
4423      }
4424      /*Enable Quadra CFA mode*/
4425      LOGH("Enabling Quadra CFA mode");
4426      mParameters.setQuadraCfaMode(true, true);
4427  
4428      setOutputImageCount(0);
4429      mInputCount = 0;
4430      mAdvancedCaptureConfigured = true;
4431      /* Display should be disabled for advanced modes */
4432      bool bSkipDisplay = true;
4433  
4434      if (getRelatedCamSyncInfo()->mode == CAM_MODE_SECONDARY) {
4435          // no Advance capture settings for Aux camera
4436          LOGH("X Secondary Camera, no need to process!! ");
4437          return rc;
4438      }
4439  
4440      /* Do not stop display if in stillmore livesnapshot */
4441      if (mParameters.isStillMoreEnabled() &&
4442              mParameters.isSeeMoreEnabled()) {
4443          bSkipDisplay = false;
4444      }
4445      if (mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
4446          rc = configureAFBracketing();
4447      } else if (mParameters.isOptiZoomEnabled()) {
4448          rc = configureOptiZoom();
4449      } else if(mParameters.isHDREnabled()) {
4450          rc = configureHDRBracketing();
4451          if (mHDRBracketingEnabled) {
4452              rc = mParameters.setToneMapMode(false, true);
4453              if (rc != NO_ERROR) {
4454                  LOGW("Failed to disable tone map during HDR");
4455              }
4456          }
4457      } else if (mParameters.isAEBracketEnabled()) {
4458          rc = mParameters.setToneMapMode(false, true);
4459          if (rc != NO_ERROR) {
4460              LOGW("Failed to disable tone map during AEBracketing");
4461          }
4462          rc = configureAEBracketing();
4463      } else if (mParameters.isStillMoreEnabled()) {
4464          bSkipDisplay = false;
4465          rc = configureStillMore();
4466      } else if ((mParameters.isChromaFlashEnabled())
4467              || (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF)
4468              || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
4469          rc = mParameters.configFrameCapture(TRUE);
4470          if (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF) {
4471              mLowLightConfigured = true;
4472          }
4473      } else if (mFlashNeeded && !mLongshotEnabled) {
4474          rc = mParameters.configFrameCapture(TRUE);
4475          mFlashConfigured = true;
4476          bSkipDisplay = false;
4477      } else {
4478          LOGH("Advanced Capture feature not enabled!! ");
4479          mAdvancedCaptureConfigured = false;
4480          bSkipDisplay = false;
4481      }
4482  
4483      if (m_postprocessor.isHalPPEnabled()) {
4484          LOGH("HALPP is enabled, check if halpp is needed for current snapshot.");
4485          configureHalPostProcess();
4486      }
4487  
4488      LOGH("Stop preview temporarily for advanced captures");
4489      setDisplaySkip(bSkipDisplay);
4490  
4491      LOGH("X rc = %d", rc);
4492      return rc;
4493  }
4494  
4495  /*===========================================================================
4496   * FUNCTION   : configureAFBracketing
4497   *
4498   * DESCRIPTION: configure AF Bracketing.
4499   *
4500   * PARAMETERS : none
4501   *
4502   * RETURN     : int32_t type of status
4503   *              NO_ERROR  -- success
4504   *              none-zero failure code
4505   *==========================================================================*/
configureAFBracketing(bool enable)4506  int32_t QCamera2HardwareInterface::configureAFBracketing(bool enable)
4507  {
4508      LOGH("E");
4509      int32_t rc = NO_ERROR;
4510      cam_af_bracketing_t *af_bracketing_need;
4511  
4512      if (mParameters.isUbiRefocus()) {
4513          af_bracketing_need =
4514                  &gCamCapability[mCameraId]->refocus_af_bracketing_need;
4515      } else {
4516          af_bracketing_need =
4517                  &gCamCapability[mCameraId]->ubifocus_af_bracketing_need;
4518      }
4519  
4520      //Enable AF Bracketing.
4521      cam_af_bracketing_t afBracket;
4522      memset(&afBracket, 0, sizeof(cam_af_bracketing_t));
4523      afBracket.enable = enable;
4524      afBracket.burst_count = af_bracketing_need->burst_count;
4525  
4526      for(int8_t i = 0; i < MAX_AF_BRACKETING_VALUES; i++) {
4527          afBracket.focus_steps[i] = af_bracketing_need->focus_steps[i];
4528          LOGH("focus_step[%d] = %d", i, afBracket.focus_steps[i]);
4529      }
4530      //Send cmd to backend to set AF Bracketing for Ubi Focus.
4531      rc = mParameters.commitAFBracket(afBracket);
4532      if ( NO_ERROR != rc ) {
4533          LOGE("cannot configure AF bracketing");
4534          return rc;
4535      }
4536      if (enable) {
4537          mParameters.set3ALock(true);
4538          mIs3ALocked = true;
4539      }
4540      LOGH("X rc = %d", rc);
4541      return rc;
4542  }
4543  
4544  /*===========================================================================
4545   * FUNCTION   : configureHDRBracketing
4546   *
4547   * DESCRIPTION: configure HDR Bracketing.
4548   *
4549   * PARAMETERS : none
4550   *
4551   * RETURN     : int32_t type of status
4552   *              NO_ERROR  -- success
4553   *              none-zero failure code
4554   *==========================================================================*/
configureHDRBracketing()4555  int32_t QCamera2HardwareInterface::configureHDRBracketing()
4556  {
4557      LOGH("E");
4558      int32_t rc = NO_ERROR;
4559  
4560      cam_hdr_bracketing_info_t& hdrBracketingSetting =
4561              gCamCapability[mCameraId]->hdr_bracketing_setting;
4562  
4563      // 'values' should be in "idx1,idx2,idx3,..." format
4564      uint32_t hdrFrameCount =
4565              hdrBracketingSetting.num_frames;
4566      LOGH("HDR values %d, %d frame count: %u",
4567            (int8_t) hdrBracketingSetting.exp_val.values[0],
4568            (int8_t) hdrBracketingSetting.exp_val.values[1],
4569            hdrFrameCount);
4570  
4571      // Enable AE Bracketing for HDR
4572      cam_exp_bracketing_t aeBracket;
4573      memset(&aeBracket, 0, sizeof(cam_exp_bracketing_t));
4574      aeBracket.mode =
4575          hdrBracketingSetting.exp_val.mode;
4576  
4577      if (aeBracket.mode == CAM_EXP_BRACKETING_ON) {
4578          mHDRBracketingEnabled = true;
4579      }
4580  
4581      String8 tmp;
4582      for (uint32_t i = 0; i < hdrFrameCount; i++) {
4583          tmp.appendFormat("%d",
4584              (int8_t) hdrBracketingSetting.exp_val.values[i]);
4585          tmp.append(",");
4586      }
4587      if (mParameters.isHDR1xFrameEnabled()
4588          && mParameters.isHDR1xExtraBufferNeeded()) {
4589              tmp.appendFormat("%d", 0);
4590              tmp.append(",");
4591      }
4592  
4593      if( !tmp.isEmpty() &&
4594          ( MAX_EXP_BRACKETING_LENGTH > tmp.length() ) ) {
4595          //Trim last comma
4596          memset(aeBracket.values, '\0', MAX_EXP_BRACKETING_LENGTH);
4597          memcpy(aeBracket.values, tmp.string(), tmp.length() - 1);
4598      }
4599  
4600      LOGH("HDR config values %s",
4601            aeBracket.values);
4602      rc = mParameters.setHDRAEBracket(aeBracket);
4603      if ( NO_ERROR != rc ) {
4604          LOGE("cannot configure HDR bracketing");
4605          return rc;
4606      }
4607      LOGH("X rc = %d", rc);
4608      return rc;
4609  }
4610  
4611  /*===========================================================================
4612   * FUNCTION   : configureAEBracketing
4613   *
4614   * DESCRIPTION: configure AE Bracketing.
4615   *
4616   * PARAMETERS : none
4617   *
4618   * RETURN     : int32_t type of status
4619   *              NO_ERROR  -- success
4620   *              none-zero failure code
4621   *==========================================================================*/
configureAEBracketing()4622  int32_t QCamera2HardwareInterface::configureAEBracketing()
4623  {
4624      LOGH("E");
4625      int32_t rc = NO_ERROR;
4626  
4627      rc = mParameters.setAEBracketing();
4628      if ( NO_ERROR != rc ) {
4629          LOGE("cannot configure AE bracketing");
4630          return rc;
4631      }
4632      LOGH("X rc = %d", rc);
4633      return rc;
4634  }
4635  
4636  /*===========================================================================
4637   * FUNCTION   : configureOptiZoom
4638   *
4639   * DESCRIPTION: configure Opti Zoom.
4640   *
4641   * PARAMETERS : none
4642   *
4643   * RETURN     : int32_t type of status
4644   *              NO_ERROR  -- success
4645   *              none-zero failure code
4646   *==========================================================================*/
configureOptiZoom()4647  int32_t QCamera2HardwareInterface::configureOptiZoom()
4648  {
4649      int32_t rc = NO_ERROR;
4650  
4651      //store current zoom level.
4652      mZoomLevel = mParameters.getParmZoomLevel();
4653  
4654      //set zoom level to 1x;
4655      mParameters.setAndCommitZoom(0);
4656  
4657      mParameters.set3ALock(true);
4658      mIs3ALocked = true;
4659  
4660      return rc;
4661  }
4662  
4663  /*===========================================================================
4664   * FUNCTION   : configureStillMore
4665   *
4666   * DESCRIPTION: configure StillMore.
4667   *
4668   * PARAMETERS : none
4669   *
4670   * RETURN     : int32_t type of status
4671   *              NO_ERROR  -- success
4672   *              none-zero failure code
4673   *==========================================================================*/
configureStillMore()4674  int32_t QCamera2HardwareInterface::configureStillMore()
4675  {
4676      int32_t rc = NO_ERROR;
4677      uint8_t burst_cnt = 0;
4678      cam_still_more_t stillmore_config;
4679      cam_still_more_t stillmore_cap;
4680  
4681      /* Disable Tone Map. If seemore is enabled, it will handle disabling it. */
4682      if (!mParameters.isSeeMoreEnabled() && !mParameters.isLTMForSeeMoreEnabled()) {
4683          rc = mParameters.setToneMapMode(false, true);
4684          if (rc != NO_ERROR) {
4685              LOGW("Failed to disable tone map during StillMore");
4686          }
4687      }
4688  
4689      /* Lock 3A */
4690      mParameters.set3ALock(true);
4691      mIs3ALocked = true;
4692  
4693      /* Disable Tintless */
4694      mParameters.setTintless(false);
4695  
4696      /* Initialize burst count from capability */
4697      stillmore_cap = mParameters.getStillMoreCapability();
4698      burst_cnt = stillmore_cap.max_burst_count;
4699  
4700      /* Reconfigure burst count from dynamic scene data */
4701      cam_dyn_img_data_t dynamic_img_data = mParameters.getDynamicImgData();
4702      if (dynamic_img_data.input_count >= stillmore_cap.min_burst_count &&
4703              dynamic_img_data.input_count <= stillmore_cap.max_burst_count) {
4704          burst_cnt = dynamic_img_data.input_count;
4705      }
4706  
4707      /* Reconfigure burst count in the case of liveshot */
4708      if (mParameters.isSeeMoreEnabled()) {
4709          burst_cnt = 1;
4710      }
4711  
4712      /* Reconfigure burst count from user input */
4713      char prop[PROPERTY_VALUE_MAX];
4714      property_get("persist.camera.imglib.stillmore", prop, "0");
4715      uint8_t burst_setprop = (uint32_t)atoi(prop);
4716      if (burst_setprop != 0)  {
4717         if ((burst_setprop < stillmore_cap.min_burst_count) ||
4718                 (burst_setprop > stillmore_cap.max_burst_count)) {
4719             burst_cnt = stillmore_cap.max_burst_count;
4720         } else {
4721             burst_cnt = burst_setprop;
4722         }
4723      }
4724  
4725      memset(&stillmore_config, 0, sizeof(cam_still_more_t));
4726      stillmore_config.burst_count = burst_cnt;
4727      mParameters.setStillMoreSettings(stillmore_config);
4728  
4729      LOGH("Stillmore burst %d", burst_cnt);
4730  
4731      return rc;
4732  }
4733  
4734  /*===========================================================================
4735   * FUNCTION   : configureHalPostProcess
4736   *
4737   * DESCRIPTION: config hal postproc (HALPP) for current snapshot.
4738   *
4739   * PARAMETERS : none
4740   *
4741   * RETURN     : int32_t type of status
4742   *              NO_ERROR  -- success
4743   *              none-zero failure code
4744   *==========================================================================*/
configureHalPostProcess()4745  int32_t QCamera2HardwareInterface::configureHalPostProcess()
4746  {
4747      LOGD("E");
4748      int32_t rc = NO_ERROR;
4749  
4750      if (!m_postprocessor.isHalPPEnabled()) {
4751          m_bNeedHalPP = FALSE;
4752          return rc;
4753      }
4754  
4755      /* check if halpp is needed in dual camera mode */
4756      if (isDualCamera()) {
4757          if (mActiveCameras == MM_CAMERA_DUAL_CAM && mBundledSnapshot == TRUE) {
4758              LOGH("Use HALPP for dual camera bundle snapshot.");
4759              m_bNeedHalPP = TRUE;
4760          }
4761          return rc;
4762      }
4763  
4764      return rc;
4765      LOGD("X");
4766  }
4767  
4768  
4769  /*===========================================================================
4770   * FUNCTION   : stopAdvancedCapture
4771   *
4772   * DESCRIPTION: stops advanced capture based on capture type
4773   *
4774   * PARAMETERS :
4775   *   @pChannel : channel.
4776   *
4777   * RETURN     : int32_t type of status
4778   *              NO_ERROR  -- success
4779   *              none-zero failure code
4780   *==========================================================================*/
stopAdvancedCapture(QCameraPicChannel * pChannel)4781  int32_t QCamera2HardwareInterface::stopAdvancedCapture(
4782          QCameraPicChannel *pChannel)
4783  {
4784      LOGH("stop bracketig");
4785      int32_t rc = NO_ERROR;
4786  
4787      if(mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
4788          rc = pChannel->stopAdvancedCapture(MM_CAMERA_AF_BRACKETING);
4789      } else if (mParameters.isChromaFlashEnabled()
4790              || (mFlashConfigured && !mLongshotEnabled)
4791              || (mLowLightConfigured == true)
4792              || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
4793          rc = pChannel->stopAdvancedCapture(MM_CAMERA_FRAME_CAPTURE);
4794          mFlashConfigured = false;
4795          mLowLightConfigured = false;
4796      } else if(mParameters.isHDREnabled()
4797              || mParameters.isAEBracketEnabled()) {
4798          rc = pChannel->stopAdvancedCapture(MM_CAMERA_AE_BRACKETING);
4799      } else if (mParameters.isOptiZoomEnabled()) {
4800          rc = pChannel->stopAdvancedCapture(MM_CAMERA_ZOOM_1X);
4801      } else if (mParameters.isStillMoreEnabled()) {
4802          LOGH("stopAdvancedCapture not needed for StillMore");
4803      } else {
4804          LOGH("No Advanced Capture feature enabled!");
4805          rc = BAD_VALUE;
4806      }
4807  
4808      m_bNeedHalPP = FALSE;
4809      return rc;
4810  }
4811  
4812  /*===========================================================================
4813   * FUNCTION   : startAdvancedCapture
4814   *
4815   * DESCRIPTION: starts advanced capture based on capture type
4816   *
4817   * PARAMETERS :
4818   *   @pChannel : channel.
4819   *
4820   * RETURN     : int32_t type of status
4821   *              NO_ERROR  -- success
4822   *              none-zero failure code
4823   *==========================================================================*/
startAdvancedCapture(QCameraPicChannel * pChannel)4824  int32_t QCamera2HardwareInterface::startAdvancedCapture(
4825          QCameraPicChannel *pChannel)
4826  {
4827      LOGH("Start bracketing");
4828      int32_t rc = NO_ERROR;
4829  
4830      if(mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
4831          rc = pChannel->startAdvancedCapture(MM_CAMERA_AF_BRACKETING);
4832      } else if (mParameters.isOptiZoomEnabled()) {
4833          rc = pChannel->startAdvancedCapture(MM_CAMERA_ZOOM_1X);
4834      } else if (mParameters.isStillMoreEnabled()) {
4835          LOGH("startAdvancedCapture not needed for StillMore");
4836      } else if (mParameters.isHDREnabled()
4837              || mParameters.isAEBracketEnabled()) {
4838          rc = pChannel->startAdvancedCapture(MM_CAMERA_AE_BRACKETING);
4839      } else if (mParameters.isChromaFlashEnabled()
4840              || (mFlashNeeded && !mLongshotEnabled)
4841              || (mLowLightConfigured == true)
4842              || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
4843          cam_capture_frame_config_t config = mParameters.getCaptureFrameConfig();
4844          rc = pChannel->startAdvancedCapture(MM_CAMERA_FRAME_CAPTURE, &config);
4845      } else {
4846          LOGE("No Advanced Capture feature enabled!");
4847          rc = BAD_VALUE;
4848      }
4849      return rc;
4850  }
4851  
4852  /*===========================================================================
4853   * FUNCTION   : preTakePicture
4854   *
4855   * DESCRIPTION: Prepare take picture impl, Restarts preview if necessary
4856   *
4857   * PARAMETERS : none
4858   *
4859   * RETURN     : int32_t type of status
4860   *              NO_ERROR  -- success
4861   *              none-zero failure code
4862   *==========================================================================*/
preTakePicture()4863  int QCamera2HardwareInterface::preTakePicture()
4864  {
4865      int32_t rc = NO_ERROR;
4866      LOGH("E");
4867      if (mParameters.getRecordingHintValue() == true) {
4868  
4869          // Give HWI control to restart preview only in single camera mode.
4870          // In dual-cam mode, this control belongs to muxer.
4871          if (getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
4872              LOGH("restart preview if rec hint is true and preview is running");
4873              stopPreview();
4874              mParameters.updateRecordingHintValue(FALSE);
4875              // start preview again
4876              rc = preparePreview();
4877              if (rc == NO_ERROR) {
4878                  rc = startPreview();
4879                  if (rc != NO_ERROR) {
4880                      unpreparePreview();
4881                  }
4882              }
4883          }
4884          else
4885          {
4886              // For dual cam mode, update the flag mPreviewRestartNeeded to true
4887              // Restart control will be handled by muxer.
4888              mPreviewRestartNeeded = true;
4889          }
4890      }
4891  
4892      LOGH("X rc = %d", rc);
4893      return rc;
4894  }
4895  
4896  /*===========================================================================
4897   * FUNCTION   : takePicture
4898   *
4899   * DESCRIPTION: take picture impl
4900   *
4901   * PARAMETERS : none
4902   *
4903   * RETURN     : int32_t type of status
4904   *              NO_ERROR  -- success
4905   *              none-zero failure code
4906   *==========================================================================*/
takePicture()4907  int QCamera2HardwareInterface::takePicture()
4908  {
4909      int rc = NO_ERROR;
4910  
4911      // Get total number for snapshots (retro + regular)
4912      uint8_t numSnapshots = mParameters.getNumOfSnapshots();
4913      // Get number of retro-active snapshots
4914      uint8_t numRetroSnapshots = mParameters.getNumOfRetroSnapshots();
4915      LOGH("E");
4916  
4917      //Set rotation value from user settings as Jpeg rotation
4918      //to configure back-end modules.
4919      mParameters.setJpegRotation(mParameters.getRotation());
4920  
4921      // Check if retro-active snapshots are not enabled
4922      if (!isRetroPicture() || !mParameters.isZSLMode()) {
4923        numRetroSnapshots = 0;
4924        LOGH("Reset retro snaphot count to zero");
4925      }
4926  
4927      //Do special configure for advanced capture modes.
4928      rc = configureAdvancedCapture();
4929      if (rc != NO_ERROR) {
4930          LOGE("Unsupported capture call");
4931          return rc;
4932      }
4933  
4934      if (mAdvancedCaptureConfigured) {
4935          numSnapshots = mParameters.getBurstCountForAdvancedCapture();
4936      }
4937  
4938      if (mActiveCameras == MM_CAMERA_DUAL_CAM && mBundledSnapshot) {
4939          char prop[PROPERTY_VALUE_MAX];
4940          memset(prop, 0, sizeof(prop));
4941          property_get("persist.camera.dualfov.jpegnum", prop, "1");
4942          int dualfov_snap_num = atoi(prop);
4943  
4944          memset(prop, 0, sizeof(prop));
4945          property_get("persist.camera.halpp", prop, "0");
4946          int halpp_enabled = atoi(prop);
4947          if(halpp_enabled == 0) {
4948              dualfov_snap_num = MM_CAMERA_MAX_CAM_CNT;
4949          }
4950  
4951          dualfov_snap_num = (dualfov_snap_num == 0) ? 1 : dualfov_snap_num;
4952          LOGD("dualfov_snap_num:%d", dualfov_snap_num);
4953          numSnapshots /= dualfov_snap_num;
4954      }
4955  
4956      LOGI("snap count = %d zsl = %d advanced = %d, active camera:%d",
4957              numSnapshots, mParameters.isZSLMode(), mAdvancedCaptureConfigured, mActiveCameras);
4958  
4959      if (mParameters.isZSLMode()) {
4960          QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
4961          QCameraPicChannel *pPicChannel = (QCameraPicChannel *)pChannel;
4962          if (NULL != pPicChannel) {
4963  
4964              if (mParameters.getofflineRAW()) {
4965                  startRAWChannel(pPicChannel);
4966                  pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_RAW];
4967                  if (pPicChannel == NULL) {
4968                      LOGE("RAW Channel is NULL in Manual capture mode");
4969                      stopRAWChannel();
4970                      return UNKNOWN_ERROR;
4971                  }
4972              }
4973  
4974              rc = configureOnlineRotation(*pPicChannel);
4975              if (rc != NO_ERROR) {
4976                  LOGE("online rotation failed");
4977                  return rc;
4978              }
4979  
4980              // start postprocessor
4981              DeferWorkArgs args;
4982              memset(&args, 0, sizeof(DeferWorkArgs));
4983  
4984              args.pprocArgs = pPicChannel;
4985  
4986              // No need to wait for mInitPProcJob here, because it was
4987              // queued in startPreview, and will definitely be processed before
4988              // mReprocJob can begin.
4989              mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START,
4990                      args);
4991              if (mReprocJob == 0) {
4992                  LOGE("Failure: Unable to start pproc");
4993                  return -ENOMEM;
4994              }
4995  
4996              // Check if all preview buffers are mapped before creating
4997              // a jpeg session as preview stream buffers are queried during the same
4998              uint8_t numStreams = pChannel->getNumOfStreams();
4999              QCameraStream *pStream = NULL;
5000              QCameraStream *pPreviewStream = NULL;
5001              for (uint8_t i = 0 ; i < numStreams ; i++ ) {
5002                  pStream = pChannel->getStreamByIndex(i);
5003                  if (!pStream)
5004                      continue;
5005                  if (CAM_STREAM_TYPE_PREVIEW == pStream->getMyType()) {
5006                      pPreviewStream = pStream;
5007                      break;
5008                  }
5009              }
5010              if (pPreviewStream != NULL) {
5011                  Mutex::Autolock l(mMapLock);
5012                  QCameraMemory *pMemory = pStream->getStreamBufs();
5013                  if (!pMemory) {
5014                      LOGE("Error!! pMemory is NULL");
5015                      return -ENOMEM;
5016                  }
5017  
5018                  uint8_t waitCnt = 2;
5019                  while (!pMemory->checkIfAllBuffersMapped() && (waitCnt > 0)) {
5020                      LOGL(" Waiting for preview buffers to be mapped");
5021                      mMapCond.waitRelative(
5022                              mMapLock, CAMERA_DEFERRED_MAP_BUF_TIMEOUT);
5023                      LOGL("Wait completed!!");
5024                      waitCnt--;
5025                  }
5026                  // If all buffers are not mapped after retries, assert
5027                  assert(pMemory->checkIfAllBuffersMapped());
5028              } else {
5029                  assert(pPreviewStream);
5030              }
5031  
5032              // Create JPEG session
5033              mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION,
5034                      args);
5035              if (mJpegJob == 0) {
5036                  LOGE("Failed to queue CREATE_JPEG_SESSION");
5037                  if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5038                          LOGE("Reprocess Deferred work was failed");
5039                  }
5040                  m_postprocessor.stop();
5041                  return -ENOMEM;
5042              }
5043  
5044              if (mAdvancedCaptureConfigured) {
5045                  rc = startAdvancedCapture(pPicChannel);
5046                  if (rc != NO_ERROR) {
5047                      LOGE("cannot start zsl advanced capture");
5048                      return rc;
5049                  }
5050              }
5051              if (mLongshotEnabled && mPrepSnapRun) {
5052                  mCameraHandle->ops->start_zsl_snapshot(
5053                          mCameraHandle->camera_handle,
5054                          pPicChannel->getMyHandle());
5055              }
5056              // If frame sync is ON and it is a SECONDARY camera,
5057              // we do not need to send the take picture command to interface
5058              // It will be handled along with PRIMARY camera takePicture request
5059              mm_camera_req_buf_t buf;
5060              memset(&buf, 0x0, sizeof(buf));
5061              if ((!mParameters.isAdvCamFeaturesEnabled() &&
5062                      !mFlashNeeded &&
5063                      !isLongshotEnabled() &&
5064                      isFrameSyncEnabled()) &&
5065                      (getRelatedCamSyncInfo()->sync_control ==
5066                      CAM_SYNC_RELATED_SENSORS_ON)) {
5067                  if (getRelatedCamSyncInfo()->mode == CAM_MODE_PRIMARY) {
5068                      buf.type = MM_CAMERA_REQ_FRAME_SYNC_BUF;
5069                      buf.num_buf_requested = numSnapshots;
5070                      rc = pPicChannel->takePicture(&buf);
5071                      if (rc != NO_ERROR) {
5072                          LOGE("FS_DBG cannot take ZSL picture, stop pproc");
5073                          if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5074                              LOGE("Reprocess Deferred work failed");
5075                              return UNKNOWN_ERROR;
5076                          }
5077                          if (NO_ERROR != waitDeferredWork(mJpegJob)) {
5078                              LOGE("Jpeg Deferred work failed");
5079                              return UNKNOWN_ERROR;
5080                          }
5081                          m_postprocessor.stop();
5082                          return rc;
5083                      }
5084                      LOGI("PRIMARY camera: send frame sync takePicture!!");
5085                  }
5086              } else {
5087                  buf.type = MM_CAMERA_REQ_SUPER_BUF;
5088                  buf.num_buf_requested = numSnapshots;
5089                  buf.num_retro_buf_requested = numRetroSnapshots;
5090                  rc = pPicChannel->takePicture(&buf);
5091                  if (rc != NO_ERROR) {
5092                      LOGE("cannot take ZSL picture, stop pproc");
5093                          if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5094                              LOGE("Reprocess Deferred work failed");
5095                              return UNKNOWN_ERROR;
5096                          }
5097                          if (NO_ERROR != waitDeferredWork(mJpegJob)) {
5098                              LOGE("Jpeg Deferred work failed");
5099                              return UNKNOWN_ERROR;
5100                          }
5101                      m_postprocessor.stop();
5102                      return rc;
5103                  }
5104              }
5105          } else {
5106              LOGE("ZSL channel is NULL");
5107              return UNKNOWN_ERROR;
5108          }
5109      } else {
5110  
5111          // start snapshot
5112          if (mParameters.isJpegPictureFormat() ||
5113                  mParameters.isNV16PictureFormat() ||
5114                  mParameters.isNV21PictureFormat()) {
5115  
5116              //STOP Preview for Non ZSL use case
5117              stopPreview();
5118  
5119              //Config CAPTURE channels
5120              rc = declareSnapshotStreams();
5121              if (NO_ERROR != rc) {
5122                  return rc;
5123              }
5124  
5125              rc = addCaptureChannel();
5126              if ((rc == NO_ERROR) &&
5127                      (NULL != m_channels[QCAMERA_CH_TYPE_CAPTURE])) {
5128  
5129                  if (!mParameters.getofflineRAW()) {
5130                      rc = configureOnlineRotation(
5131                          *m_channels[QCAMERA_CH_TYPE_CAPTURE]);
5132                      if (rc != NO_ERROR) {
5133                          LOGE("online rotation failed");
5134                          delChannel(QCAMERA_CH_TYPE_CAPTURE);
5135                          return rc;
5136                      }
5137                  }
5138  
5139                  DeferWorkArgs args;
5140                  memset(&args, 0, sizeof(DeferWorkArgs));
5141  
5142                  args.pprocArgs = m_channels[QCAMERA_CH_TYPE_CAPTURE];
5143  
5144                  // No need to wait for mInitPProcJob here, because it was
5145                  // queued in startPreview, and will definitely be processed before
5146                  // mReprocJob can begin.
5147                  mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START,
5148                          args);
5149                  if (mReprocJob == 0) {
5150                      LOGE("Failure: Unable to start pproc");
5151                      return -ENOMEM;
5152                  }
5153  
5154                  // Create JPEG session
5155                  mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION,
5156                          args);
5157                  if (mJpegJob == 0) {
5158                      LOGE("Failed to queue CREATE_JPEG_SESSION");
5159                      if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5160                          LOGE("Reprocess Deferred work was failed");
5161                      }
5162                      m_postprocessor.stop();
5163                      return -ENOMEM;
5164                  }
5165  
5166                  // start catpure channel
5167                  rc =  m_channels[QCAMERA_CH_TYPE_CAPTURE]->start();
5168                  if (rc != NO_ERROR) {
5169                      LOGE("cannot start capture channel");
5170                      if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5171                          LOGE("Reprocess Deferred work failed");
5172                          return UNKNOWN_ERROR;
5173                      }
5174                      if (NO_ERROR != waitDeferredWork(mJpegJob)) {
5175                          LOGE("Jpeg Deferred work failed");
5176                          return UNKNOWN_ERROR;
5177                      }
5178                      delChannel(QCAMERA_CH_TYPE_CAPTURE);
5179                      return rc;
5180                  }
5181  
5182                  QCameraPicChannel *pCapChannel =
5183                      (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_CAPTURE];
5184                  if (NULL != pCapChannel) {
5185                      if (mParameters.isUbiFocusEnabled() ||
5186                              mParameters.isUbiRefocus() ||
5187                              mParameters.isChromaFlashEnabled()) {
5188                          rc = startAdvancedCapture(pCapChannel);
5189                          if (rc != NO_ERROR) {
5190                              LOGE("cannot start advanced capture");
5191                              return rc;
5192                          }
5193                      }
5194                  }
5195                  if ( mLongshotEnabled ) {
5196                      rc = longShot();
5197                      if (NO_ERROR != rc) {
5198                          if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5199                              LOGE("Reprocess Deferred work failed");
5200                              return UNKNOWN_ERROR;
5201                          }
5202                          if (NO_ERROR != waitDeferredWork(mJpegJob)) {
5203                              LOGE("Jpeg Deferred work failed");
5204                              return UNKNOWN_ERROR;
5205                          }
5206                          delChannel(QCAMERA_CH_TYPE_CAPTURE);
5207                          return rc;
5208                      }
5209                  }
5210              } else {
5211                  LOGE("cannot add capture channel");
5212                  delChannel(QCAMERA_CH_TYPE_CAPTURE);
5213                  return rc;
5214              }
5215          } else {
5216              // Stop Preview before taking NZSL snapshot
5217              stopPreview();
5218  
5219              rc = mParameters.updateRAW(gCamCapability[mCameraId]->raw_dim[0]);
5220              if (NO_ERROR != rc) {
5221                  LOGE("Raw dimension update failed %d", rc);
5222                  return rc;
5223              }
5224  
5225              rc = declareSnapshotStreams();
5226              if (NO_ERROR != rc) {
5227                  LOGE("RAW stream info configuration failed %d", rc);
5228                  return rc;
5229              }
5230  
5231              rc = addChannel(QCAMERA_CH_TYPE_RAW);
5232              if (rc == NO_ERROR) {
5233                  // start postprocessor
5234                  if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
5235                      LOGE("Reprocess Deferred work failed");
5236                      return UNKNOWN_ERROR;
5237                  }
5238  
5239                  rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]);
5240                  if (rc != NO_ERROR) {
5241                      LOGE("cannot start postprocessor");
5242                      delChannel(QCAMERA_CH_TYPE_RAW);
5243                      return rc;
5244                  }
5245  
5246                  rc = startChannel(QCAMERA_CH_TYPE_RAW);
5247                  if (rc != NO_ERROR) {
5248                      LOGE("cannot start raw channel");
5249                      m_postprocessor.stop();
5250                      delChannel(QCAMERA_CH_TYPE_RAW);
5251                      return rc;
5252                  }
5253              } else {
5254                  LOGE("cannot add raw channel");
5255                  return rc;
5256              }
5257          }
5258      }
5259  
5260      //When take picture, stop sending preview callbacks to APP
5261      m_stateMachine.setPreviewCallbackNeeded(false);
5262      LOGI("X rc = %d", rc);
5263      return rc;
5264  }
5265  
5266  /*===========================================================================
5267   * FUNCTION   : configureOnlineRotation
5268   *
5269   * DESCRIPTION: Configure backend with expected rotation for snapshot stream
5270   *
5271   * PARAMETERS :
5272   *    @ch     : Channel containing a snapshot stream
5273   *
5274   * RETURN     : int32_t type of status
5275   *              NO_ERROR  -- success
5276   *              none-zero failure code
5277   *==========================================================================*/
configureOnlineRotation(QCameraChannel & ch)5278  int32_t QCamera2HardwareInterface::configureOnlineRotation(QCameraChannel &ch)
5279  {
5280      int rc = NO_ERROR;
5281      uint32_t streamId = 0;
5282      QCameraStream *pStream = NULL;
5283  
5284      for (uint8_t i = 0; i < ch.getNumOfStreams(); i++) {
5285          QCameraStream *stream = ch.getStreamByIndex(i);
5286          if ((NULL != stream) &&
5287                  ((CAM_STREAM_TYPE_SNAPSHOT == stream->getMyType())
5288                  || (CAM_STREAM_TYPE_RAW == stream->getMyType()))) {
5289              pStream = stream;
5290              break;
5291          }
5292      }
5293  
5294      if (NULL == pStream) {
5295          LOGE("No snapshot stream found!");
5296          return BAD_VALUE;
5297      }
5298  
5299      streamId = pStream->getMyServerID();
5300      // Update online rotation configuration
5301      rc = mParameters.addOnlineRotation(mParameters.getJpegRotation(), streamId,
5302              mParameters.getDeviceRotation());
5303      if (rc != NO_ERROR) {
5304          LOGE("addOnlineRotation failed %d", rc);
5305          return rc;
5306      }
5307  
5308      return rc;
5309  }
5310  
5311  /*===========================================================================
5312   * FUNCTION   : declareSnapshotStreams
5313   *
5314   * DESCRIPTION: Configure backend with expected snapshot streams
5315   *
5316   * PARAMETERS : none
5317   *
5318   * RETURN     : int32_t type of status
5319   *              NO_ERROR  -- success
5320   *              none-zero failure code
5321   *==========================================================================*/
declareSnapshotStreams()5322  int32_t QCamera2HardwareInterface::declareSnapshotStreams()
5323  {
5324      int rc = NO_ERROR;
5325  
5326      // Update stream info configuration
5327      rc = mParameters.setStreamConfigure(true, mLongshotEnabled, false);
5328      if (rc != NO_ERROR) {
5329          LOGE("setStreamConfigure failed %d", rc);
5330          return rc;
5331      }
5332  
5333      return rc;
5334  }
5335  
5336  /*===========================================================================
5337   * FUNCTION   : longShot
5338   *
5339   * DESCRIPTION: Queue one more ZSL frame
5340   *              in the longshot pipe.
5341   *
5342   * PARAMETERS : none
5343   *
5344   * RETURN     : int32_t type of status
5345   *              NO_ERROR  -- success
5346   *              none-zero failure code
5347   *==========================================================================*/
longShot()5348  int32_t QCamera2HardwareInterface::longShot()
5349  {
5350      int32_t rc = NO_ERROR;
5351      uint8_t numSnapshots = mParameters.getNumOfSnapshots();
5352      QCameraPicChannel *pChannel = NULL;
5353  
5354      if (mParameters.isZSLMode()) {
5355          pChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
5356      } else {
5357          pChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_CAPTURE];
5358      }
5359  
5360      if (NULL != pChannel) {
5361          mm_camera_req_buf_t buf;
5362          memset(&buf, 0x0, sizeof(buf));
5363          buf.type = MM_CAMERA_REQ_SUPER_BUF;
5364          buf.num_buf_requested = numSnapshots;
5365          rc = pChannel->takePicture(&buf);
5366      } else {
5367          LOGE("Capture channel not initialized!");
5368          rc = NO_INIT;
5369          goto end;
5370      }
5371  
5372  end:
5373      return rc;
5374  }
5375  
5376  /*===========================================================================
5377   * FUNCTION   : stopCaptureChannel
5378   *
5379   * DESCRIPTION: Stops capture channel
5380   *
5381   * PARAMETERS :
5382   *   @destroy : Set to true to stop and delete camera channel.
5383   *              Set to false to only stop capture channel.
5384   *
5385   * RETURN     : int32_t type of status
5386   *              NO_ERROR  -- success
5387   *              none-zero failure code
5388   *==========================================================================*/
stopCaptureChannel(bool destroy)5389  int QCamera2HardwareInterface::stopCaptureChannel(bool destroy)
5390  {
5391      int rc = NO_ERROR;
5392      if (mParameters.isJpegPictureFormat() ||
5393          mParameters.isNV16PictureFormat() ||
5394          mParameters.isNV21PictureFormat()) {
5395          mParameters.setQuadraCfaMode(false, true);
5396          rc = stopChannel(QCAMERA_CH_TYPE_CAPTURE);
5397          if (destroy && (NO_ERROR == rc)) {
5398              // Destroy camera channel but dont release context
5399              waitDeferredWork(mJpegJob);
5400              rc = delChannel(QCAMERA_CH_TYPE_CAPTURE, false);
5401          }
5402      }
5403  
5404      return rc;
5405  }
5406  
5407  /*===========================================================================
5408   * FUNCTION   : cancelPicture
5409   *
5410   * DESCRIPTION: cancel picture impl
5411   *
5412   * PARAMETERS : none
5413   *
5414   * RETURN     : int32_t type of status
5415   *              NO_ERROR  -- success
5416   *              none-zero failure code
5417   *==========================================================================*/
cancelPicture()5418  int QCamera2HardwareInterface::cancelPicture()
5419  {
5420      waitDeferredWork(mReprocJob);
5421      waitDeferredWork(mJpegJob);
5422  
5423      //stop post processor
5424      m_postprocessor.stop();
5425  
5426      unconfigureAdvancedCapture();
5427      LOGH("Enable display frames again");
5428      setDisplaySkip(FALSE);
5429  
5430      if (mParameters.isZSLMode()) {
5431          QCameraPicChannel *pPicChannel = NULL;
5432          if (mParameters.getofflineRAW()) {
5433              pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_RAW];
5434          } else {
5435              pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
5436          }
5437          if (NULL != pPicChannel) {
5438              pPicChannel->cancelPicture();
5439              stopRAWChannel();
5440              stopAdvancedCapture(pPicChannel);
5441          }
5442      } else {
5443  
5444          // normal capture case
5445          if (mParameters.isJpegPictureFormat() ||
5446              mParameters.isNV16PictureFormat() ||
5447              mParameters.isNV21PictureFormat()) {
5448              stopChannel(QCAMERA_CH_TYPE_CAPTURE);
5449              delChannel(QCAMERA_CH_TYPE_CAPTURE);
5450          } else {
5451              stopChannel(QCAMERA_CH_TYPE_RAW);
5452              delChannel(QCAMERA_CH_TYPE_RAW);
5453          }
5454      }
5455  
5456      return NO_ERROR;
5457  }
5458  
5459  /*===========================================================================
5460   * FUNCTION   : captureDone
5461   *
5462   * DESCRIPTION: Function called when the capture is completed before encoding
5463   *
5464   * PARAMETERS : none
5465   *
5466   * RETURN     : none
5467   *==========================================================================*/
captureDone()5468  void QCamera2HardwareInterface::captureDone()
5469  {
5470      qcamera_sm_internal_evt_payload_t *payload =
5471         (qcamera_sm_internal_evt_payload_t *)
5472         malloc(sizeof(qcamera_sm_internal_evt_payload_t));
5473      if (NULL != payload) {
5474          memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
5475          payload->evt_type = QCAMERA_INTERNAL_EVT_ZSL_CAPTURE_DONE;
5476          int32_t rc = processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
5477          if (rc != NO_ERROR) {
5478              LOGE("processEvt ZSL capture done failed");
5479              free(payload);
5480              payload = NULL;
5481          }
5482      } else {
5483          LOGE("No memory for ZSL capture done event");
5484      }
5485  }
5486  
5487  /*===========================================================================
5488   * FUNCTION   : Live_Snapshot_thread
5489   *
5490   * DESCRIPTION: Seperate thread for taking live snapshot during recording
5491   *
5492   * PARAMETERS : @data - pointer to QCamera2HardwareInterface class object
5493   *
5494   * RETURN     : none
5495   *==========================================================================*/
Live_Snapshot_thread(void * data)5496  void* Live_Snapshot_thread (void* data)
5497  {
5498  
5499      QCamera2HardwareInterface *hw = reinterpret_cast<QCamera2HardwareInterface *>(data);
5500      if (!hw) {
5501          LOGE("take_picture_thread: NULL camera device");
5502          return (void *)BAD_VALUE;
5503      }
5504      if (hw->bLiveSnapshot) {
5505          hw->takeLiveSnapshot_internal();
5506      } else {
5507          hw->cancelLiveSnapshot_internal();
5508      }
5509      return (void* )NULL;
5510  }
5511  
5512  /*===========================================================================
5513   * FUNCTION   : Int_Pic_thread
5514   *
5515   * DESCRIPTION: Seperate thread for taking snapshot triggered by camera backend
5516   *
5517   * PARAMETERS : @data - pointer to QCamera2HardwareInterface class object
5518   *
5519   * RETURN     : none
5520   *==========================================================================*/
Int_Pic_thread(void * data)5521  void* Int_Pic_thread (void* data)
5522  {
5523      int rc = NO_ERROR;
5524  
5525      QCamera2HardwareInterface *hw = reinterpret_cast<QCamera2HardwareInterface *>(data);
5526  
5527      if (!hw) {
5528          LOGE("take_picture_thread: NULL camera device");
5529          return (void *)BAD_VALUE;
5530      }
5531  
5532      bool JpegMemOpt = false;
5533      char raw_format[PROPERTY_VALUE_MAX];
5534  
5535      memset(raw_format, 0, sizeof(raw_format));
5536  
5537      rc = hw->takeBackendPic_internal(&JpegMemOpt, &raw_format[0]);
5538      if (rc == NO_ERROR) {
5539          hw->checkIntPicPending(JpegMemOpt, &raw_format[0]);
5540      } else {
5541          //Snapshot attempt not successful, we need to do cleanup here
5542          hw->clearIntPendingEvents();
5543      }
5544  
5545      return (void* )NULL;
5546  }
5547  
5548  /*===========================================================================
5549   * FUNCTION   : takeLiveSnapshot
5550   *
5551   * DESCRIPTION: take live snapshot during recording
5552   *
5553   * PARAMETERS : none
5554   *
5555   * RETURN     : int32_t type of status
5556   *              NO_ERROR  -- success
5557   *              none-zero failure code
5558   *==========================================================================*/
takeLiveSnapshot()5559  int QCamera2HardwareInterface::takeLiveSnapshot()
5560  {
5561      int rc = NO_ERROR;
5562      if (mLiveSnapshotThread != 0) {
5563          pthread_join(mLiveSnapshotThread,NULL);
5564          mLiveSnapshotThread = 0;
5565      }
5566      bLiveSnapshot = true;
5567      rc= pthread_create(&mLiveSnapshotThread, NULL, Live_Snapshot_thread, (void *) this);
5568      if (!rc) {
5569          pthread_setname_np(mLiveSnapshotThread, "CAM_liveSnap");
5570      }
5571      return rc;
5572  }
5573  
5574  /*===========================================================================
5575   * FUNCTION   : takePictureInternal
5576   *
5577   * DESCRIPTION: take snapshot triggered by backend
5578   *
5579   * PARAMETERS : none
5580   *
5581   * RETURN     : int32_t type of status
5582   *              NO_ERROR  -- success
5583   *              none-zero failure code
5584   *==========================================================================*/
takePictureInternal()5585  int QCamera2HardwareInterface::takePictureInternal()
5586  {
5587      int rc = NO_ERROR;
5588      rc= pthread_create(&mIntPicThread, NULL, Int_Pic_thread, (void *) this);
5589      if (!rc) {
5590          pthread_setname_np(mIntPicThread, "CAM_IntPic");
5591      }
5592      return rc;
5593  }
5594  
5595  /*===========================================================================
5596   * FUNCTION   : checkIntPicPending
5597   *
5598   * DESCRIPTION: timed wait for jpeg completion event, and send
5599   *                        back completion event to backend
5600   *
5601   * PARAMETERS : none
5602   *
5603   * RETURN     : none
5604   *==========================================================================*/
checkIntPicPending(bool JpegMemOpt,char * raw_format)5605  void QCamera2HardwareInterface::checkIntPicPending(bool JpegMemOpt, char *raw_format)
5606  {
5607      bool bSendToBackend = true;
5608      cam_int_evt_params_t params;
5609      int rc = NO_ERROR;
5610  
5611      struct timespec   ts;
5612      struct timeval    tp;
5613      gettimeofday(&tp, NULL);
5614      ts.tv_sec  = tp.tv_sec + 5;
5615      ts.tv_nsec = tp.tv_usec * 1000;
5616  
5617      if (true == m_bIntJpegEvtPending ||
5618          (true == m_bIntRawEvtPending)) {
5619          //Waiting in HAL for snapshot taken notification
5620          pthread_mutex_lock(&m_int_lock);
5621          rc = pthread_cond_timedwait(&m_int_cond, &m_int_lock, &ts);
5622          if (ETIMEDOUT == rc || 0x0 == m_BackendFileName[0]) {
5623              //Hit a timeout, or some spurious activity
5624              bSendToBackend = false;
5625          }
5626  
5627          if (true == m_bIntJpegEvtPending) {
5628              params.event_type = 0;
5629              mParameters.getStreamFormat(CAM_STREAM_TYPE_SNAPSHOT, params.picture_format);
5630          } else if (true == m_bIntRawEvtPending) {
5631              params.event_type = 1;
5632              mParameters.getStreamFormat(CAM_STREAM_TYPE_RAW, params.picture_format);
5633          }
5634          pthread_mutex_unlock(&m_int_lock);
5635  
5636          if (true == m_bIntJpegEvtPending) {
5637              //Attempting to restart preview after taking JPEG snapshot
5638              lockAPI();
5639              rc = processAPI(QCAMERA_SM_EVT_SNAPSHOT_DONE, NULL);
5640              unlockAPI();
5641              m_postprocessor.setJpegMemOpt(JpegMemOpt);
5642          } else if (true == m_bIntRawEvtPending) {
5643              //Attempting to restart preview after taking RAW snapshot
5644              stopChannel(QCAMERA_CH_TYPE_RAW);
5645              delChannel(QCAMERA_CH_TYPE_RAW);
5646              //restoring the old raw format
5647              property_set("persist.camera.raw.format", raw_format);
5648          }
5649  
5650          if (true == bSendToBackend) {
5651              //send event back to server with the file path
5652              params.dim = m_postprocessor.m_dst_dim;
5653              memcpy(&params.path[0], &m_BackendFileName[0], QCAMERA_MAX_FILEPATH_LENGTH);
5654              memset(&m_BackendFileName[0], 0x0, QCAMERA_MAX_FILEPATH_LENGTH);
5655              params.size = mBackendFileSize;
5656              rc = mParameters.setIntEvent(params);
5657          }
5658  
5659          clearIntPendingEvents();
5660      }
5661  
5662      return;
5663  }
5664  
5665  /*===========================================================================
5666   * FUNCTION   : takeBackendPic_internal
5667   *
5668   * DESCRIPTION: take snapshot triggered by backend
5669   *
5670   * PARAMETERS : none
5671   *
5672   * RETURN     : int32_t type of status
5673   *              NO_ERROR  -- success
5674   *              none-zero failure code
5675   *==========================================================================*/
takeBackendPic_internal(bool * JpegMemOpt,char * raw_format)5676  int QCamera2HardwareInterface::takeBackendPic_internal(bool *JpegMemOpt, char *raw_format)
5677  {
5678      int rc = NO_ERROR;
5679      qcamera_api_result_t apiResult;
5680  
5681      lockAPI();
5682      //Set rotation value from user settings as Jpeg rotation
5683      //to configure back-end modules.
5684      mParameters.setJpegRotation(mParameters.getRotation());
5685  
5686      setRetroPicture(0);
5687      /* Prepare snapshot in case LED needs to be flashed */
5688      if (mFlashNeeded == 1 || mParameters.isChromaFlashEnabled()) {
5689          // Start Preparing for normal Frames
5690          LOGH("Start Prepare Snapshot");
5691          /* Prepare snapshot in case LED needs to be flashed */
5692          rc = processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL);
5693          if (rc == NO_ERROR) {
5694              waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, &apiResult);
5695              rc = apiResult.status;
5696          }
5697          LOGH("Prep Snapshot done rc = %d", rc);
5698          mPrepSnapRun = true;
5699      }
5700      unlockAPI();
5701  
5702      if (true == m_bIntJpegEvtPending) {
5703          //Attempting to take JPEG snapshot
5704          if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
5705              LOGE("Init PProc Deferred work failed");
5706              return UNKNOWN_ERROR;
5707          }
5708          *JpegMemOpt = m_postprocessor.getJpegMemOpt();
5709          m_postprocessor.setJpegMemOpt(false);
5710  
5711          /* capture */
5712          lockAPI();
5713          LOGH("Capturing internal snapshot");
5714          rc = processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL);
5715          if (rc == NO_ERROR) {
5716              waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult);
5717              rc = apiResult.status;
5718          }
5719          unlockAPI();
5720      } else if (true == m_bIntRawEvtPending) {
5721          //Attempting to take RAW snapshot
5722          (void)JpegMemOpt;
5723          stopPreview();
5724  
5725          //getting the existing raw format type
5726          property_get("persist.camera.raw.format", raw_format, "17");
5727          //setting it to a default know value for this task
5728          property_set("persist.camera.raw.format", "18");
5729  
5730          rc = addChannel(QCAMERA_CH_TYPE_RAW);
5731          if (rc == NO_ERROR) {
5732              // start postprocessor
5733              if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
5734                  LOGE("Init PProc Deferred work failed");
5735                  return UNKNOWN_ERROR;
5736              }
5737              rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]);
5738              if (rc != NO_ERROR) {
5739                  LOGE("cannot start postprocessor");
5740                  delChannel(QCAMERA_CH_TYPE_RAW);
5741                  return rc;
5742              }
5743  
5744              rc = startChannel(QCAMERA_CH_TYPE_RAW);
5745              if (rc != NO_ERROR) {
5746                  LOGE("cannot start raw channel");
5747                  m_postprocessor.stop();
5748                  delChannel(QCAMERA_CH_TYPE_RAW);
5749                  return rc;
5750              }
5751          } else {
5752              LOGE("cannot add raw channel");
5753              return rc;
5754          }
5755      }
5756  
5757      return rc;
5758  }
5759  
5760  /*===========================================================================
5761   * FUNCTION   : clearIntPendingEvents
5762   *
5763   * DESCRIPTION: clear internal pending events pertaining to backend
5764   *                        snapshot requests
5765   *
5766   * PARAMETERS : none
5767   *
5768   * RETURN     : int32_t type of status
5769   *              NO_ERROR  -- success
5770   *              none-zero failure code
5771   *==========================================================================*/
clearIntPendingEvents()5772  void QCamera2HardwareInterface::clearIntPendingEvents()
5773  {
5774      int rc = NO_ERROR;
5775  
5776      if (true == m_bIntRawEvtPending) {
5777          preparePreview();
5778          startPreview();
5779      }
5780      if (true == m_bIntJpegEvtPending) {
5781          if (false == mParameters.isZSLMode()) {
5782              lockAPI();
5783              rc = processAPI(QCAMERA_SM_EVT_START_PREVIEW, NULL);
5784              unlockAPI();
5785          }
5786      }
5787  
5788      pthread_mutex_lock(&m_int_lock);
5789      if (true == m_bIntJpegEvtPending) {
5790          m_bIntJpegEvtPending = false;
5791      } else if (true == m_bIntRawEvtPending) {
5792          m_bIntRawEvtPending = false;
5793      }
5794      pthread_mutex_unlock(&m_int_lock);
5795      return;
5796  }
5797  
5798  /*===========================================================================
5799   * FUNCTION   : takeLiveSnapshot_internal
5800   *
5801   * DESCRIPTION: take live snapshot during recording
5802   *
5803   * PARAMETERS : none
5804   *
5805   * RETURN     : int32_t type of status
5806   *              NO_ERROR  -- success
5807   *              none-zero failure code
5808   *==========================================================================*/
takeLiveSnapshot_internal()5809  int QCamera2HardwareInterface::takeLiveSnapshot_internal()
5810  {
5811      int rc = NO_ERROR;
5812  
5813      QCameraChannel *pChannel = NULL;
5814      QCameraChannel *pPreviewChannel = NULL;
5815      QCameraStream  *pPreviewStream = NULL;
5816      QCameraStream  *pStream = NULL;
5817  
5818      //Set rotation value from user settings as Jpeg rotation
5819      //to configure back-end modules.
5820      mParameters.setJpegRotation(mParameters.getRotation());
5821  
5822      // Configure advanced capture
5823      rc = configureAdvancedCapture();
5824      if (rc != NO_ERROR) {
5825          LOGE("Unsupported capture call");
5826          goto end;
5827      }
5828  
5829      if (isLowPowerMode()) {
5830          pChannel = m_channels[QCAMERA_CH_TYPE_VIDEO];
5831      } else {
5832          pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
5833      }
5834  
5835      if (NULL == pChannel) {
5836          LOGE("Snapshot/Video channel not initialized");
5837          rc = NO_INIT;
5838          goto end;
5839      }
5840  
5841      // Check if all preview buffers are mapped before creating
5842      // a jpeg session as preview stream buffers are queried during the same
5843      pPreviewChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
5844      if (pPreviewChannel != NULL) {
5845          uint32_t numStreams = pPreviewChannel->getNumOfStreams();
5846  
5847          for (uint8_t i = 0 ; i < numStreams ; i++ ) {
5848              pStream = pPreviewChannel->getStreamByIndex(i);
5849              if (!pStream)
5850                  continue;
5851              if (CAM_STREAM_TYPE_PREVIEW == pStream->getMyType()) {
5852                  pPreviewStream = pStream;
5853                  break;
5854              }
5855          }
5856  
5857          if (pPreviewStream != NULL) {
5858              Mutex::Autolock l(mMapLock);
5859              QCameraMemory *pMemory = pStream->getStreamBufs();
5860              if (!pMemory) {
5861                  LOGE("Error!! pMemory is NULL");
5862                  return -ENOMEM;
5863              }
5864  
5865              uint8_t waitCnt = 2;
5866              while (!pMemory->checkIfAllBuffersMapped() && (waitCnt > 0)) {
5867                  LOGL(" Waiting for preview buffers to be mapped");
5868                  mMapCond.waitRelative(
5869                          mMapLock, CAMERA_DEFERRED_MAP_BUF_TIMEOUT);
5870                  LOGL("Wait completed!!");
5871                  waitCnt--;
5872              }
5873              // If all buffers are not mapped after retries, assert
5874              assert(pMemory->checkIfAllBuffersMapped());
5875          } else {
5876              assert(pPreviewStream);
5877          }
5878      }
5879  
5880      DeferWorkArgs args;
5881      memset(&args, 0, sizeof(DeferWorkArgs));
5882  
5883      args.pprocArgs = pChannel;
5884  
5885      // No need to wait for mInitPProcJob here, because it was
5886      // queued in startPreview, and will definitely be processed before
5887      // mReprocJob can begin.
5888      mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START,
5889              args);
5890      if (mReprocJob == 0) {
5891          LOGE("Failed to queue CMD_DEF_PPROC_START");
5892          rc = -ENOMEM;
5893          goto end;
5894      }
5895  
5896      // Create JPEG session
5897      mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION,
5898              args);
5899      if (mJpegJob == 0) {
5900          LOGE("Failed to queue CREATE_JPEG_SESSION");
5901          if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5902              LOGE("Reprocess Deferred work was failed");
5903          }
5904          m_postprocessor.stop();
5905          rc = -ENOMEM;
5906          goto end;
5907      }
5908  
5909      if (isLowPowerMode()) {
5910          mm_camera_req_buf_t buf;
5911          memset(&buf, 0x0, sizeof(buf));
5912          buf.type = MM_CAMERA_REQ_SUPER_BUF;
5913          buf.num_buf_requested = 1;
5914          rc = ((QCameraVideoChannel*)pChannel)->takePicture(&buf);
5915          goto end;
5916      }
5917  
5918      //Disable reprocess for 4K liveshot case
5919      if (!mParameters.is4k2kVideoResolution()) {
5920          rc = configureOnlineRotation(*m_channels[QCAMERA_CH_TYPE_SNAPSHOT]);
5921          if (rc != NO_ERROR) {
5922              LOGE("online rotation failed");
5923              if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5924                  LOGE("Reprocess Deferred work was failed");
5925              }
5926              if (NO_ERROR != waitDeferredWork(mJpegJob)) {
5927                  LOGE("Jpeg Deferred work was failed");
5928              }
5929              m_postprocessor.stop();
5930              return rc;
5931          }
5932      }
5933  
5934      if ((NULL != pChannel) && (mParameters.isTNRSnapshotEnabled())) {
5935          QCameraStream *pStream = NULL;
5936          for (uint32_t i = 0 ; i < pChannel->getNumOfStreams(); i++ ) {
5937              pStream = pChannel->getStreamByIndex(i);
5938              if ((NULL != pStream) &&
5939                      (CAM_STREAM_TYPE_SNAPSHOT == pStream->getMyType())) {
5940                  break;
5941              }
5942          }
5943          if (pStream != NULL) {
5944              LOGD("REQUEST_FRAMES event for TNR snapshot");
5945              cam_stream_parm_buffer_t param;
5946              memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
5947              param.type = CAM_STREAM_PARAM_TYPE_REQUEST_FRAMES;
5948              param.frameRequest.enableStream = 1;
5949              rc = pStream->setParameter(param);
5950              if (rc != NO_ERROR) {
5951                  LOGE("Stream Event REQUEST_FRAMES failed");
5952              }
5953              goto end;
5954          }
5955      }
5956  
5957      // start snapshot channel
5958      if ((rc == NO_ERROR) && (NULL != pChannel)) {
5959          // Do not link metadata stream for 4K2k resolution
5960          // as CPP processing would be done on snapshot stream and not
5961          // reprocess stream
5962          if (!mParameters.is4k2kVideoResolution()) {
5963              // Find and try to link a metadata stream from preview channel
5964              QCameraChannel *pMetaChannel = NULL;
5965              QCameraStream *pMetaStream = NULL;
5966              QCameraStream *pPreviewStream = NULL;
5967  
5968              if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
5969                  pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
5970                  uint32_t streamNum = pMetaChannel->getNumOfStreams();
5971                  QCameraStream *pStream = NULL;
5972                  for (uint32_t i = 0 ; i < streamNum ; i++ ) {
5973                      pStream = pMetaChannel->getStreamByIndex(i);
5974                      if (NULL != pStream) {
5975                          if (CAM_STREAM_TYPE_METADATA == pStream->getMyType()) {
5976                              pMetaStream = pStream;
5977                          } else if ((CAM_STREAM_TYPE_PREVIEW == pStream->getMyType())
5978                                  && (!mParameters.isHfrMode())
5979                                  && (mParameters.isLinkPreviewForLiveShot())) {
5980                              // Do not link preview stream for
5981                              // 1)HFR live snapshot,Thumbnail will not be derived from
5982                              //   preview for HFR live snapshot.
5983                              // 2)persist.camera.linkpreview is 0
5984                              pPreviewStream = pStream;
5985                          }
5986                      }
5987                  }
5988              }
5989  
5990              if ((NULL != pMetaChannel) && (NULL != pMetaStream)) {
5991                  rc = pChannel->linkStream(pMetaChannel, pMetaStream);
5992                  if (NO_ERROR != rc) {
5993                      LOGE("Metadata stream link failed %d", rc);
5994                  }
5995              }
5996              if ((NULL != pMetaChannel) && (NULL != pPreviewStream)) {
5997                  rc = pChannel->linkStream(pMetaChannel, pPreviewStream);
5998                  if (NO_ERROR != rc) {
5999                      LOGE("Preview stream link failed %d", rc);
6000                  }
6001              }
6002          }
6003          rc = pChannel->start();
6004      }
6005  
6006  end:
6007      if (rc != NO_ERROR) {
6008          rc = processAPI(QCAMERA_SM_EVT_CANCEL_PICTURE, NULL);
6009          rc = sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
6010      }
6011      return rc;
6012  }
6013  
6014  /*===========================================================================
6015   * FUNCTION   : cancelLiveSnapshot
6016   *
6017   * DESCRIPTION: cancel current live snapshot request
6018   *
6019   * PARAMETERS : none
6020   *
6021   * RETURN     : int32_t type of status
6022   *              NO_ERROR  -- success
6023   *              none-zero failure code
6024   *==========================================================================*/
cancelLiveSnapshot()6025  int QCamera2HardwareInterface::cancelLiveSnapshot()
6026  {
6027      int rc = NO_ERROR;
6028      if (mLiveSnapshotThread != 0) {
6029          pthread_join(mLiveSnapshotThread,NULL);
6030          mLiveSnapshotThread = 0;
6031      }
6032      bLiveSnapshot = false;
6033      rc= pthread_create(&mLiveSnapshotThread, NULL, Live_Snapshot_thread, (void *) this);
6034      if (!rc) {
6035          pthread_setname_np(mLiveSnapshotThread, "CAM_cancel_liveSnap");
6036      }
6037      return rc;
6038  }
6039  
6040  /*===========================================================================
6041   * FUNCTION   : cancelLiveSnapshot_internal
6042   *
6043   * DESCRIPTION: cancel live snapshot during recording
6044   *
6045   * PARAMETERS : none
6046   *
6047   * RETURN     : int32_t type of status
6048   *              NO_ERROR  -- success
6049   *              none-zero failure code
6050   *==========================================================================*/
cancelLiveSnapshot_internal()6051  int QCamera2HardwareInterface::cancelLiveSnapshot_internal() {
6052      int rc = NO_ERROR;
6053  
6054      unconfigureAdvancedCapture();
6055      LOGH("Enable display frames again");
6056      setDisplaySkip(FALSE);
6057  
6058      //wait for deferred (reprocess and jpeg) threads to finish
6059      waitDeferredWork(mReprocJob);
6060      waitDeferredWork(mJpegJob);
6061      //stop post processor
6062      m_postprocessor.stop();
6063  
6064      // stop snapshot channel
6065      if (!mParameters.isTNRSnapshotEnabled()) {
6066          rc = stopChannel(QCAMERA_CH_TYPE_SNAPSHOT);
6067      } else {
6068          QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
6069          if (NULL != pChannel) {
6070              QCameraStream *pStream = NULL;
6071              for (uint32_t i = 0 ; i < pChannel->getNumOfStreams(); i++ ) {
6072                  pStream = pChannel->getStreamByIndex(i);
6073                  if ((NULL != pStream) &&
6074                          (CAM_STREAM_TYPE_SNAPSHOT ==
6075                          pStream->getMyType())) {
6076                      break;
6077                  }
6078              }
6079              if (pStream != NULL) {
6080                  LOGD("REQUEST_FRAMES event for TNR snapshot");
6081                  cam_stream_parm_buffer_t param;
6082                  memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
6083                  param.type = CAM_STREAM_PARAM_TYPE_REQUEST_FRAMES;
6084                  param.frameRequest.enableStream = 0;
6085                  rc = pStream->setParameter(param);
6086                  if (rc != NO_ERROR) {
6087                      LOGE("Stream Event REQUEST_FRAMES failed");
6088                  }
6089              }
6090          }
6091      }
6092  
6093      return rc;
6094  }
6095  
6096  /*===========================================================================
6097   * FUNCTION   : putParameters
6098   *
6099   * DESCRIPTION: put parameters string impl
6100   *
6101   * PARAMETERS :
6102   *   @parms   : parameters string to be released
6103   *
6104   * RETURN     : int32_t type of status
6105   *              NO_ERROR  -- success
6106   *              none-zero failure code
6107   *==========================================================================*/
putParameters(char * parms)6108  int QCamera2HardwareInterface::putParameters(char *parms)
6109  {
6110      free(parms);
6111      return NO_ERROR;
6112  }
6113  
6114  /*===========================================================================
6115   * FUNCTION   : sendCommand
6116   *
6117   * DESCRIPTION: send command impl
6118   *
6119   * PARAMETERS :
6120   *   @command : command to be executed
6121   *   @arg1    : optional argument 1
6122   *   @arg2    : optional argument 2
6123   *
6124   * RETURN     : int32_t type of status
6125   *              NO_ERROR  -- success
6126   *              none-zero failure code
6127   *==========================================================================*/
sendCommand(int32_t command,__unused int32_t & arg1,__unused int32_t & arg2)6128  int QCamera2HardwareInterface::sendCommand(int32_t command,
6129          __unused int32_t &arg1, __unused int32_t &arg2)
6130  {
6131      int rc = NO_ERROR;
6132  
6133      switch (command) {
6134  #ifndef VANILLA_HAL
6135      case CAMERA_CMD_LONGSHOT_ON:
6136          arg1 = arg2 = 0;
6137          // Longshot can only be enabled when image capture
6138          // is not active.
6139          if ( !m_stateMachine.isCaptureRunning() ) {
6140              LOGI("Longshot Enabled");
6141              mLongshotEnabled = true;
6142              rc = mParameters.setLongshotEnable(mLongshotEnabled);
6143  
6144              // Due to recent buffer count optimizations
6145              // ZSL might run with considerably less buffers
6146              // when not in longshot mode. Preview needs to
6147              // restart in this case.
6148              if (isZSLMode() && m_stateMachine.isPreviewRunning()) {
6149                  QCameraChannel *pChannel = NULL;
6150                  QCameraStream *pSnapStream = NULL;
6151                  pChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
6152                  if (NULL != pChannel) {
6153                      QCameraStream *pStream = NULL;
6154                      for (uint32_t i = 0; i < pChannel->getNumOfStreams(); i++) {
6155                          pStream = pChannel->getStreamByIndex(i);
6156                          if (pStream != NULL) {
6157                              if (pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT)) {
6158                                  pSnapStream = pStream;
6159                                  break;
6160                              }
6161                          }
6162                      }
6163                      if (NULL != pSnapStream) {
6164                          uint8_t required = 0;
6165                          required = getBufNumRequired(CAM_STREAM_TYPE_SNAPSHOT);
6166                          if (pSnapStream->getBufferCount() < required) {
6167                              // We restart here, to reset the FPS and no
6168                              // of buffers as per the requirement of longshot usecase.
6169                              arg1 = QCAMERA_SM_EVT_RESTART_PERVIEW;
6170                              if (getRelatedCamSyncInfo()->sync_control ==
6171                                      CAM_SYNC_RELATED_SENSORS_ON) {
6172                                  arg2 = QCAMERA_SM_EVT_DELAYED_RESTART;
6173                              }
6174                          }
6175                      }
6176                  }
6177              }
6178              //
6179              mPrepSnapRun = false;
6180              mCACDoneReceived = FALSE;
6181          } else {
6182              rc = NO_INIT;
6183          }
6184          break;
6185      case CAMERA_CMD_LONGSHOT_OFF:
6186          if ( mLongshotEnabled && m_stateMachine.isCaptureRunning() ) {
6187              cancelPicture();
6188              processEvt(QCAMERA_SM_EVT_SNAPSHOT_DONE, NULL);
6189              QCameraChannel *pZSLChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
6190              if (isZSLMode() && (NULL != pZSLChannel) && mPrepSnapRun) {
6191                  mCameraHandle->ops->stop_zsl_snapshot(
6192                          mCameraHandle->camera_handle,
6193                          pZSLChannel->getMyHandle());
6194              }
6195          }
6196          mPrepSnapRun = false;
6197          LOGI("Longshot Disabled");
6198          mLongshotEnabled = false;
6199          rc = mParameters.setLongshotEnable(mLongshotEnabled);
6200          mCACDoneReceived = FALSE;
6201          break;
6202      case CAMERA_CMD_HISTOGRAM_ON:
6203      case CAMERA_CMD_HISTOGRAM_OFF:
6204          rc = setHistogram(command == CAMERA_CMD_HISTOGRAM_ON? true : false);
6205          LOGH("Histogram -> %s",
6206                mParameters.isHistogramEnabled() ? "Enabled" : "Disabled");
6207          break;
6208  #endif
6209      case CAMERA_CMD_START_FACE_DETECTION:
6210      case CAMERA_CMD_STOP_FACE_DETECTION:
6211          mParameters.setFaceDetectionOption(command == CAMERA_CMD_START_FACE_DETECTION? true : false);
6212          rc = setFaceDetection(command == CAMERA_CMD_START_FACE_DETECTION? true : false);
6213          LOGH("FaceDetection -> %s",
6214                mParameters.isFaceDetectionEnabled() ? "Enabled" : "Disabled");
6215          break;
6216  #ifndef VANILLA_HAL
6217      case CAMERA_CMD_HISTOGRAM_SEND_DATA:
6218  #endif
6219      default:
6220          rc = NO_ERROR;
6221          break;
6222      }
6223      return rc;
6224  }
6225  
6226  /*===========================================================================
6227   * FUNCTION   : registerFaceImage
6228   *
6229   * DESCRIPTION: register face image impl
6230   *
6231   * PARAMETERS :
6232   *   @img_ptr : ptr to image buffer
6233   *   @config  : ptr to config struct about input image info
6234   *   @faceID  : [OUT] face ID to uniquely identifiy the registered face image
6235   *
6236   * RETURN     : int32_t type of status
6237   *              NO_ERROR  -- success
6238   *              none-zero failure code
6239   *==========================================================================*/
registerFaceImage(void * img_ptr,cam_pp_offline_src_config_t * config,int32_t & faceID)6240  int QCamera2HardwareInterface::registerFaceImage(void *img_ptr,
6241                                                   cam_pp_offline_src_config_t *config,
6242                                                   int32_t &faceID)
6243  {
6244      int rc = NO_ERROR;
6245      faceID = -1;
6246  
6247      if (img_ptr == NULL || config == NULL) {
6248          LOGE("img_ptr or config is NULL");
6249          return BAD_VALUE;
6250      }
6251  
6252      // allocate ion memory for source image
6253      QCameraHeapMemory *imgBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
6254      if (imgBuf == NULL) {
6255          LOGE("Unable to new heap memory obj for image buf");
6256          return NO_MEMORY;
6257      }
6258  
6259      rc = imgBuf->allocate(1, config->input_buf_planes.plane_info.frame_len);
6260      if (rc < 0) {
6261          LOGE("Unable to allocate heap memory for image buf");
6262          delete imgBuf;
6263          return NO_MEMORY;
6264      }
6265  
6266      void *pBufPtr = imgBuf->getPtr(0);
6267      if (pBufPtr == NULL) {
6268          LOGE("image buf is NULL");
6269          imgBuf->deallocate();
6270          delete imgBuf;
6271          return NO_MEMORY;
6272      }
6273      memcpy(pBufPtr, img_ptr, config->input_buf_planes.plane_info.frame_len);
6274      //Do cache ops before sending for reprocess
6275      imgBuf->cacheOps(0, ION_IOC_CLEAN_INV_CACHES);
6276  
6277      cam_pp_feature_config_t pp_feature;
6278      memset(&pp_feature, 0, sizeof(cam_pp_feature_config_t));
6279      pp_feature.feature_mask = CAM_QCOM_FEATURE_REGISTER_FACE;
6280      QCameraReprocessChannel *pChannel =
6281          addOfflineReprocChannel(*config, pp_feature, NULL, NULL);
6282  
6283      if (pChannel == NULL) {
6284          LOGE("fail to add offline reprocess channel");
6285          imgBuf->deallocate();
6286          delete imgBuf;
6287          return UNKNOWN_ERROR;
6288      }
6289  
6290      rc = pChannel->start();
6291      if (rc != NO_ERROR) {
6292          LOGE("Cannot start reprocess channel");
6293          imgBuf->deallocate();
6294          delete imgBuf;
6295          delete pChannel;
6296          return rc;
6297      }
6298  
6299      ssize_t bufSize = imgBuf->getSize(0);
6300      if (BAD_INDEX != bufSize) {
6301          rc = pChannel->doReprocess(imgBuf->getFd(0), imgBuf->getPtr(0),
6302                  (size_t)bufSize, faceID);
6303      } else {
6304          LOGE("Failed to retrieve buffer size (bad index)");
6305          return UNKNOWN_ERROR;
6306      }
6307  
6308      // done with register face image, free imgbuf and delete reprocess channel
6309      imgBuf->deallocate();
6310      delete imgBuf;
6311      imgBuf = NULL;
6312      pChannel->stop();
6313      delete pChannel;
6314      pChannel = NULL;
6315  
6316      return rc;
6317  }
6318  
6319  /*===========================================================================
6320   * FUNCTION   : release
6321   *
6322   * DESCRIPTION: release camera resource impl
6323   *
6324   * PARAMETERS : none
6325   *
6326   * RETURN     : int32_t type of status
6327   *              NO_ERROR  -- success
6328   *              none-zero failure code
6329   *==========================================================================*/
release()6330  int QCamera2HardwareInterface::release()
6331  {
6332      // stop and delete all channels
6333      for (int i = 0; i <QCAMERA_CH_TYPE_MAX ; i++) {
6334          if (m_channels[i] != NULL) {
6335              stopChannel((qcamera_ch_type_enum_t)i);
6336              delChannel((qcamera_ch_type_enum_t)i);
6337          }
6338      }
6339  
6340      return NO_ERROR;
6341  }
6342  
6343  /*===========================================================================
6344   * FUNCTION   : dump
6345   *
6346   * DESCRIPTION: camera status dump impl
6347   *
6348   * PARAMETERS :
6349   *   @fd      : fd for the buffer to be dumped with camera status
6350   *
6351   * RETURN     : int32_t type of status
6352   *              NO_ERROR  -- success
6353   *              none-zero failure code
6354   *==========================================================================*/
dump(int fd)6355  int QCamera2HardwareInterface::dump(int fd)
6356  {
6357      dprintf(fd, "\n Camera HAL information Begin \n");
6358      dprintf(fd, "Camera ID: %d \n", mCameraId);
6359      dprintf(fd, "StoreMetaDataInFrame: %d \n", mStoreMetaDataInFrame);
6360      dprintf(fd, "\n Configuration: %s", mParameters.dump().string());
6361      dprintf(fd, "\n State Information: %s", m_stateMachine.dump().string());
6362      dprintf(fd, "\n Camera HAL information End \n");
6363  
6364      /* send UPDATE_DEBUG_LEVEL to the backend so that they can read the
6365         debug level property */
6366      mParameters.updateDebugLevel();
6367      return NO_ERROR;
6368  }
6369  
6370  /*===========================================================================
6371   * FUNCTION   : processAPI
6372   *
6373   * DESCRIPTION: process API calls from upper layer
6374   *
6375   * PARAMETERS :
6376   *   @api         : API to be processed
6377   *   @api_payload : ptr to API payload if any
6378   *
6379   * RETURN     : int32_t type of status
6380   *              NO_ERROR  -- success
6381   *              none-zero failure code
6382   *==========================================================================*/
processAPI(qcamera_sm_evt_enum_t api,void * api_payload)6383  int QCamera2HardwareInterface::processAPI(qcamera_sm_evt_enum_t api, void *api_payload)
6384  {
6385      int ret = DEAD_OBJECT;
6386  
6387      if (m_smThreadActive) {
6388          ret = m_stateMachine.procAPI(api, api_payload);
6389      }
6390  
6391      return ret;
6392  }
6393  
6394  /*===========================================================================
6395   * FUNCTION   : processEvt
6396   *
6397   * DESCRIPTION: process Evt from backend via mm-camera-interface
6398   *
6399   * PARAMETERS :
6400   *   @evt         : event type to be processed
6401   *   @evt_payload : ptr to event payload if any
6402   *
6403   * RETURN     : int32_t type of status
6404   *              NO_ERROR  -- success
6405   *              none-zero failure code
6406   *==========================================================================*/
processEvt(qcamera_sm_evt_enum_t evt,void * evt_payload)6407  int QCamera2HardwareInterface::processEvt(qcamera_sm_evt_enum_t evt, void *evt_payload)
6408  {
6409      return m_stateMachine.procEvt(evt, evt_payload);
6410  }
6411  
6412  /*===========================================================================
6413   * FUNCTION   : processSyncEvt
6414   *
6415   * DESCRIPTION: process synchronous Evt from backend
6416   *
6417   * PARAMETERS :
6418   *   @evt         : event type to be processed
6419   *   @evt_payload : ptr to event payload if any
6420   *
6421   * RETURN     : int32_t type of status
6422   *              NO_ERROR  -- success
6423   *              none-zero failure code
6424   *==========================================================================*/
processSyncEvt(qcamera_sm_evt_enum_t evt,void * evt_payload)6425  int QCamera2HardwareInterface::processSyncEvt(qcamera_sm_evt_enum_t evt, void *evt_payload)
6426  {
6427      int rc = NO_ERROR;
6428  
6429      pthread_mutex_lock(&m_evtLock);
6430      rc =  processEvt(evt, evt_payload);
6431      if (rc == NO_ERROR) {
6432          memset(&m_evtResult, 0, sizeof(qcamera_api_result_t));
6433          while (m_evtResult.request_api != evt) {
6434              pthread_cond_wait(&m_evtCond, &m_evtLock);
6435          }
6436          rc =  m_evtResult.status;
6437      }
6438      pthread_mutex_unlock(&m_evtLock);
6439  
6440      return rc;
6441  }
6442  
6443  /*===========================================================================
6444   * FUNCTION   : evtHandle
6445   *
6446   * DESCRIPTION: Function registerd to mm-camera-interface to handle backend events
6447   *
6448   * PARAMETERS :
6449   *   @camera_handle : event type to be processed
6450   *   @evt           : ptr to event
6451   *   @user_data     : user data ptr
6452   *
6453   * RETURN     : none
6454   *==========================================================================*/
camEvtHandle(uint32_t,mm_camera_event_t * evt,void * user_data)6455  void QCamera2HardwareInterface::camEvtHandle(uint32_t /*camera_handle*/,
6456                                            mm_camera_event_t *evt,
6457                                            void *user_data)
6458  {
6459      QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)user_data;
6460      if (obj && evt) {
6461          mm_camera_event_t *payload =
6462              (mm_camera_event_t *)malloc(sizeof(mm_camera_event_t));
6463          if (NULL != payload) {
6464              *payload = *evt;
6465              //peek into the event, if this is an eztune event from server,
6466              //then we don't need to post it to the SM Qs, we shud directly
6467              //spawn a thread and get the job done (jpeg or raw snapshot)
6468              switch (payload->server_event_type) {
6469                  case CAM_EVENT_TYPE_INT_TAKE_JPEG:
6470                      //Received JPEG trigger from eztune
6471                      if (false == obj->m_bIntJpegEvtPending) {
6472                          pthread_mutex_lock(&obj->m_int_lock);
6473                          obj->m_bIntJpegEvtPending = true;
6474                          pthread_mutex_unlock(&obj->m_int_lock);
6475                          obj->takePictureInternal();
6476                      }
6477                      free(payload);
6478                      break;
6479                  case CAM_EVENT_TYPE_INT_TAKE_RAW:
6480                      //Received RAW trigger from eztune
6481                      if (false == obj->m_bIntRawEvtPending) {
6482                          pthread_mutex_lock(&obj->m_int_lock);
6483                          obj->m_bIntRawEvtPending = true;
6484                          pthread_mutex_unlock(&obj->m_int_lock);
6485                          obj->takePictureInternal();
6486                      }
6487                      free(payload);
6488                      break;
6489                  case CAM_EVENT_TYPE_DAEMON_DIED:
6490                      {
6491                          Mutex::Autolock l(obj->mDefLock);
6492                          obj->mDefCond.broadcast();
6493                          LOGH("broadcast mDefCond signal\n");
6494                      }
6495                  default:
6496                      obj->processEvt(QCAMERA_SM_EVT_EVT_NOTIFY, payload);
6497                      break;
6498              }
6499          }
6500      } else {
6501          LOGE("NULL user_data");
6502      }
6503  }
6504  
6505  /*===========================================================================
6506   * FUNCTION   : jpegEvtHandle
6507   *
6508   * DESCRIPTION: Function registerd to mm-jpeg-interface to handle jpeg events
6509   *
6510   * PARAMETERS :
6511   *   @status    : status of jpeg job
6512   *   @client_hdl: jpeg client handle
6513   *   @jobId     : jpeg job Id
6514   *   @p_ouput   : ptr to jpeg output result struct
6515   *   @userdata  : user data ptr
6516   *
6517   * RETURN     : none
6518   *==========================================================================*/
jpegEvtHandle(jpeg_job_status_t status,uint32_t,uint32_t jobId,mm_jpeg_output_t * p_output,void * userdata)6519  void QCamera2HardwareInterface::jpegEvtHandle(jpeg_job_status_t status,
6520                                                uint32_t /*client_hdl*/,
6521                                                uint32_t jobId,
6522                                                mm_jpeg_output_t *p_output,
6523                                                void *userdata)
6524  {
6525      QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)userdata;
6526      if (obj) {
6527          qcamera_jpeg_evt_payload_t *payload =
6528              (qcamera_jpeg_evt_payload_t *)malloc(sizeof(qcamera_jpeg_evt_payload_t));
6529          if (NULL != payload) {
6530              memset(payload, 0, sizeof(qcamera_jpeg_evt_payload_t));
6531              payload->status = status;
6532              payload->jobId = jobId;
6533              if (p_output != NULL) {
6534                  payload->out_data = *p_output;
6535              }
6536              obj->processEvt(QCAMERA_SM_EVT_JPEG_EVT_NOTIFY, payload);
6537          }
6538      } else {
6539          LOGE("NULL user_data");
6540      }
6541  }
6542  
6543  /*===========================================================================
6544   * FUNCTION   : thermalEvtHandle
6545   *
6546   * DESCRIPTION: routine to handle thermal event notification
6547   *
6548   * PARAMETERS :
6549   *   @level      : thermal level
6550   *   @userdata   : userdata passed in during registration
6551   *   @data       : opaque data from thermal client
6552   *
6553   * RETURN     : int32_t type of status
6554   *              NO_ERROR  -- success
6555   *              none-zero failure code
6556   *==========================================================================*/
thermalEvtHandle(qcamera_thermal_level_enum_t * level,void * userdata,void * data)6557  int QCamera2HardwareInterface::thermalEvtHandle(
6558          qcamera_thermal_level_enum_t *level, void *userdata, void *data)
6559  {
6560      if (!mCameraOpened) {
6561          LOGH("Camera is not opened, no need to handle thermal evt");
6562          return NO_ERROR;
6563      }
6564  
6565      // Make sure thermal events are logged
6566      LOGH("level = %d, userdata = %p, data = %p",
6567           *level, userdata, data);
6568      //We don't need to lockAPI, waitAPI here. QCAMERA_SM_EVT_THERMAL_NOTIFY
6569      // becomes an aync call. This also means we can only pass payload
6570      // by value, not by address.
6571      return processAPI(QCAMERA_SM_EVT_THERMAL_NOTIFY, (void *)level);
6572  }
6573  
6574  /*===========================================================================
6575   * FUNCTION   : sendEvtNotify
6576   *
6577   * DESCRIPTION: send event notify to notify thread
6578   *
6579   * PARAMETERS :
6580   *   @msg_type: msg type to be sent
6581   *   @ext1    : optional extension1
6582   *   @ext2    : optional extension2
6583   *
6584   * RETURN     : int32_t type of status
6585   *              NO_ERROR  -- success
6586   *              none-zero failure code
6587   *==========================================================================*/
sendEvtNotify(int32_t msg_type,int32_t ext1,int32_t ext2)6588  int32_t QCamera2HardwareInterface::sendEvtNotify(int32_t msg_type,
6589                                                   int32_t ext1,
6590                                                   int32_t ext2)
6591  {
6592      qcamera_callback_argm_t cbArg;
6593      memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
6594      cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK;
6595      cbArg.msg_type = msg_type;
6596      cbArg.ext1 = ext1;
6597      cbArg.ext2 = ext2;
6598      return m_cbNotifier.notifyCallback(cbArg);
6599  }
6600  
6601  /*===========================================================================
6602   * FUNCTION   : processAEInfo
6603   *
6604   * DESCRIPTION: process AE updates
6605   *
6606   * PARAMETERS :
6607   *   @ae_params: current AE parameters
6608   *
6609   * RETURN     : None
6610   *==========================================================================*/
processAEInfo(cam_3a_params_t & ae_params)6611  int32_t QCamera2HardwareInterface::processAEInfo(cam_3a_params_t &ae_params)
6612  {
6613      mParameters.updateAEInfo(ae_params);
6614      if (mParameters.isInstantAECEnabled()) {
6615          // Reset Instant AEC info only if instant aec enabled.
6616          bool bResetInstantAec = false;
6617          if (ae_params.settled) {
6618              // If AEC settled, reset instant AEC
6619              bResetInstantAec = true;
6620          } else if ((mParameters.isInstantCaptureEnabled()) &&
6621                  (mInstantAecFrameCount >= mParameters.getAecFrameBoundValue())) {
6622              // if AEC not settled, and instant capture enabled,
6623              // reset instant AEC only when frame count is
6624              // more or equal to AEC frame bound value.
6625              bResetInstantAec = true;
6626          } else if ((mParameters.isInstantAECEnabled()) &&
6627                  (mInstantAecFrameCount >= mParameters.getAecSkipDisplayFrameBound())) {
6628              // if AEC not settled, and only instant AEC enabled,
6629              // reset instant AEC only when frame count is
6630              // more or equal to AEC skip display frame bound value.
6631              bResetInstantAec = true;
6632          }
6633  
6634          if (bResetInstantAec) {
6635              LOGD("setting instant AEC to false");
6636              mParameters.setInstantAEC(false, true);
6637              mInstantAecFrameCount = 0;
6638          }
6639      }
6640      return NO_ERROR;
6641  }
6642  
6643  /*===========================================================================
6644   * FUNCTION   : processFocusPositionInfo
6645   *
6646   * DESCRIPTION: process AF updates
6647   *
6648   * PARAMETERS :
6649   *   @cur_pos_info: current lens position
6650   *
6651   * RETURN     : None
6652   *==========================================================================*/
processFocusPositionInfo(cam_focus_pos_info_t & cur_pos_info)6653  int32_t QCamera2HardwareInterface::processFocusPositionInfo(cam_focus_pos_info_t &cur_pos_info)
6654  {
6655      mParameters.updateCurrentFocusPosition(cur_pos_info);
6656      return NO_ERROR;
6657  }
6658  
6659  /*===========================================================================
6660   * FUNCTION   : processAutoFocusEvent
6661   *
6662   * DESCRIPTION: process auto focus event
6663   *
6664   * PARAMETERS :
6665   *   @focus_data: struct containing auto focus result info
6666   *
6667   * RETURN     : int32_t type of status
6668   *              NO_ERROR  -- success
6669   *              none-zero failure code
6670   *==========================================================================*/
processAutoFocusEvent(cam_auto_focus_data_t & focus_data)6671  int32_t QCamera2HardwareInterface::processAutoFocusEvent(cam_auto_focus_data_t &focus_data)
6672  {
6673      int32_t ret = NO_ERROR;
6674      LOGH("E");
6675  
6676      if (getRelatedCamSyncInfo()->mode == CAM_MODE_SECONDARY) {
6677          // Ignore focus updates
6678          LOGH("X Secondary Camera, no need to process!! ");
6679          return ret;
6680      }
6681      cam_focus_mode_type focusMode = mParameters.getFocusMode();
6682      LOGH("[AF_DBG]  focusMode=%d, focusState=%d isDepth=%d",
6683               focusMode, focus_data.focus_state, focus_data.isDepth);
6684  
6685      switch (focusMode) {
6686      case CAM_FOCUS_MODE_AUTO:
6687      case CAM_FOCUS_MODE_MACRO:
6688          // ignore AF event if AF was already cancelled meanwhile
6689          if (!mActiveAF) {
6690              break;
6691          }
6692          // If the HAL focus mode is different from AF INFINITY focus mode, send event to app
6693          if ((focus_data.focus_mode == CAM_FOCUS_MODE_INFINITY) &&
6694                  (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) {
6695              ret = sendEvtNotify(CAMERA_MSG_FOCUS, true, 0);
6696              mActiveAF = false; // reset the mActiveAF in this special case
6697              break;
6698          }
6699  
6700          //while transitioning from CAF->Auto/Macro, we might receive CAF related
6701          //events (PASSIVE_*) due to timing. Ignore such events if any.
6702          if ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN) ||
6703                  (focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
6704                  (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED)) {
6705              break;
6706          }
6707  
6708          //This is just an intermediate update to HAL indicating focus is in progress. No need
6709          //to send this event to app. Same applies to INACTIVE state as well.
6710          if ((focus_data.focus_state == CAM_AF_STATE_ACTIVE_SCAN) ||
6711                  (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) {
6712              break;
6713          }
6714          // update focus distance
6715          mParameters.updateFocusDistances(&focus_data.focus_dist);
6716  
6717          //flush any old snapshot frames in ZSL Q which are not focused.
6718          if (mParameters.isZSLMode() && focus_data.flush_info.needFlush ) {
6719              QCameraPicChannel *pZSLChannel =
6720                      (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
6721              if (NULL != pZSLChannel) {
6722                  //flush the zsl-buffer
6723                  uint32_t flush_frame_idx = focus_data.flush_info.focused_frame_idx;
6724                  LOGD("flush the zsl-buffer before frame = %u.", flush_frame_idx);
6725                  pZSLChannel->flushSuperbuffer(flush_frame_idx);
6726              }
6727          }
6728  
6729          //send event to app finally
6730          LOGI("Send AF DOne event to app");
6731          ret = sendEvtNotify(CAMERA_MSG_FOCUS,
6732                              (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED), 0);
6733          break;
6734      case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
6735      case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
6736  
6737          // If the HAL focus mode is different from AF INFINITY focus mode, send event to app
6738          if ((focus_data.focus_mode == CAM_FOCUS_MODE_INFINITY) &&
6739                  (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) {
6740              ret = sendEvtNotify(CAMERA_MSG_FOCUS, false, 0);
6741              mActiveAF = false; // reset the mActiveAF in this special case
6742              break;
6743          }
6744  
6745          //If AutoFocus() is triggered while in CAF mode, ignore all CAF events (PASSIVE_*) and
6746          //process/wait for only ACTIVE_* events.
6747          if (((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
6748                  (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED) ||
6749                  (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN)) && mActiveAF) {
6750              break;
6751          }
6752  
6753          if (!bDepthAFCallbacks && focus_data.isDepth &&
6754                  (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN)) {
6755              LOGD("Skip sending scan state to app, if depth focus");
6756              break;
6757          }
6758  
6759          //These are the AF states for which we need to send notification to app in CAF mode.
6760          //This includes both regular CAF (PASSIVE) events as well as ACTIVE events ( in case
6761          //AF is triggered while in CAF mode)
6762          if ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
6763                  (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED) ||
6764                  (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED) ||
6765                  (focus_data.focus_state == CAM_AF_STATE_NOT_FOCUSED_LOCKED)) {
6766  
6767              // update focus distance
6768              mParameters.updateFocusDistances(&focus_data.focus_dist);
6769  
6770              if (mParameters.isZSLMode() && focus_data.flush_info.needFlush ) {
6771                  QCameraPicChannel *pZSLChannel =
6772                          (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
6773                  if (NULL != pZSLChannel) {
6774                      //flush the zsl-buffer
6775                      uint32_t flush_frame_idx = focus_data.flush_info.focused_frame_idx;
6776                      LOGD("flush the zsl-buffer before frame = %u.", flush_frame_idx);
6777                      pZSLChannel->flushSuperbuffer(flush_frame_idx);
6778                  }
6779              }
6780  
6781              if (mActiveAF) {
6782                  LOGI("Send AF Done event to app");
6783              }
6784              ret = sendEvtNotify(CAMERA_MSG_FOCUS,
6785                      ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
6786                      (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED)), 0);
6787          }
6788          ret = sendEvtNotify(CAMERA_MSG_FOCUS_MOVE,
6789                  (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN), 0);
6790          break;
6791      case CAM_FOCUS_MODE_INFINITY:
6792      case CAM_FOCUS_MODE_FIXED:
6793      case CAM_FOCUS_MODE_EDOF:
6794      default:
6795          LOGH("no ops for autofocus event in focusmode %d", focusMode);
6796          break;
6797      }
6798  
6799      //Reset mActiveAF once we receive focus done event
6800      if ((focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED) ||
6801              (focus_data.focus_state == CAM_AF_STATE_NOT_FOCUSED_LOCKED)) {
6802          mActiveAF = false;
6803      }
6804  
6805      LOGH("X");
6806      return ret;
6807  }
6808  
6809  /*===========================================================================
6810   * FUNCTION   : processZoomEvent
6811   *
6812   * DESCRIPTION: process zoom event
6813   *
6814   * PARAMETERS :
6815   *   @crop_info : crop info as a result of zoom operation
6816   *
6817   * RETURN     : int32_t type of status
6818   *              NO_ERROR  -- success
6819   *              none-zero failure code
6820   *==========================================================================*/
processZoomEvent(cam_crop_data_t & crop_info)6821  int32_t QCamera2HardwareInterface::processZoomEvent(cam_crop_data_t &crop_info)
6822  {
6823      int32_t ret = NO_ERROR;
6824  
6825      for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
6826          if (m_channels[i] != NULL) {
6827              ret = m_channels[i]->processZoomDone(mPreviewWindow, crop_info);
6828          }
6829      }
6830      return ret;
6831  }
6832  
6833  /*===========================================================================
6834   * FUNCTION   : processZSLCaptureDone
6835   *
6836   * DESCRIPTION: process ZSL capture done events
6837   *
6838   * PARAMETERS : None
6839   *
6840   * RETURN     : int32_t type of status
6841   *              NO_ERROR  -- success
6842   *              none-zero failure code
6843   *==========================================================================*/
processZSLCaptureDone()6844  int32_t QCamera2HardwareInterface::processZSLCaptureDone()
6845  {
6846      int rc = NO_ERROR;
6847  
6848      if (++mInputCount >= mParameters.getBurstCountForAdvancedCapture()) {
6849          rc = unconfigureAdvancedCapture();
6850      }
6851  
6852      return rc;
6853  }
6854  
6855  /*===========================================================================
6856   * FUNCTION   : processRetroAECUnlock
6857   *
6858   * DESCRIPTION: process retro burst AEC unlock events
6859   *
6860   * PARAMETERS : None
6861   *
6862   * RETURN     : int32_t type of status
6863   *              NO_ERROR  -- success
6864   *              none-zero failure code
6865   *==========================================================================*/
processRetroAECUnlock()6866  int32_t QCamera2HardwareInterface::processRetroAECUnlock()
6867  {
6868      int rc = NO_ERROR;
6869  
6870      LOGH("LED assisted AF Release AEC Lock");
6871      rc = mParameters.setAecLock("false");
6872      if (NO_ERROR != rc) {
6873          LOGE("Error setting AEC lock");
6874          return rc;
6875      }
6876  
6877      rc = mParameters.commitParameters();
6878      if (NO_ERROR != rc) {
6879          LOGE("Error during camera parameter commit");
6880      } else {
6881          m_bLedAfAecLock = FALSE;
6882      }
6883  
6884      return rc;
6885  }
6886  
6887  /*===========================================================================
6888   * FUNCTION   : processHDRData
6889   *
6890   * DESCRIPTION: process HDR scene events
6891   *
6892   * PARAMETERS :
6893   *   @hdr_scene : HDR scene event data
6894   *
6895   * RETURN     : int32_t type of status
6896   *              NO_ERROR  -- success
6897   *              none-zero failure code
6898   *==========================================================================*/
processHDRData(__unused cam_asd_hdr_scene_data_t hdr_scene)6899  int32_t QCamera2HardwareInterface::processHDRData(
6900          __unused cam_asd_hdr_scene_data_t hdr_scene)
6901  {
6902      int rc = NO_ERROR;
6903  
6904  #ifndef VANILLA_HAL
6905      if (hdr_scene.is_hdr_scene &&
6906        (hdr_scene.hdr_confidence > HDR_CONFIDENCE_THRESHOLD) &&
6907        mParameters.isAutoHDREnabled()) {
6908          m_HDRSceneEnabled = true;
6909      } else {
6910          m_HDRSceneEnabled = false;
6911      }
6912      mParameters.setHDRSceneEnable(m_HDRSceneEnabled);
6913  
6914      if ( msgTypeEnabled(CAMERA_MSG_META_DATA) ) {
6915  
6916          size_t data_len = sizeof(int);
6917          size_t buffer_len = 1 *sizeof(int)       //meta type
6918                            + 1 *sizeof(int)       //data len
6919                            + 1 *sizeof(int);      //data
6920          camera_memory_t *hdrBuffer = mGetMemory(-1,
6921                                                   buffer_len,
6922                                                   1,
6923                                                   mCallbackCookie);
6924          if ( NULL == hdrBuffer ) {
6925              LOGE("Not enough memory for auto HDR data");
6926              return NO_MEMORY;
6927          }
6928  
6929          int *pHDRData = (int *)hdrBuffer->data;
6930          if (pHDRData == NULL) {
6931              LOGE("memory data ptr is NULL");
6932              return UNKNOWN_ERROR;
6933          }
6934  
6935          pHDRData[0] = CAMERA_META_DATA_HDR;
6936          pHDRData[1] = (int)data_len;
6937          pHDRData[2] = m_HDRSceneEnabled;
6938  
6939          qcamera_callback_argm_t cbArg;
6940          memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
6941          cbArg.cb_type = QCAMERA_DATA_CALLBACK;
6942          cbArg.msg_type = CAMERA_MSG_META_DATA;
6943          cbArg.data = hdrBuffer;
6944          cbArg.user_data = hdrBuffer;
6945          cbArg.cookie = this;
6946          cbArg.release_cb = releaseCameraMemory;
6947          rc = m_cbNotifier.notifyCallback(cbArg);
6948          if (rc != NO_ERROR) {
6949              LOGE("fail sending auto HDR notification");
6950              hdrBuffer->release(hdrBuffer);
6951          }
6952      }
6953  
6954      LOGH("hdr_scene_data: processHDRData: %d %f",
6955            hdr_scene.is_hdr_scene,
6956            hdr_scene.hdr_confidence);
6957  
6958  #endif
6959    return rc;
6960  }
6961  
6962  /*===========================================================================
6963   * FUNCTION   : processLEDCalibration
6964   *
6965   * DESCRIPTION: process LED calibration result
6966   *
6967   * PARAMETERS :
6968   *   @value : Calibaration result
6969   *
6970   * RETURN     : int32_t type of status
6971   *              NO_ERROR  -- success
6972   *              none-zero failure code
6973   *==========================================================================*/
processLEDCalibration(int32_t value)6974  int32_t QCamera2HardwareInterface::processLEDCalibration(int32_t value)
6975  {
6976      int32_t rc = NO_ERROR;
6977  #ifndef VANILLA_HAL
6978      if (mParameters.getDualLedCalibration()) {
6979          LOGH("Dual LED calibration value = %d", value);
6980          int32_t data_len = sizeof(value);
6981          int32_t buffer_len = sizeof(int)       //meta type
6982                  + sizeof(int)                  //data len
6983                  + data_len;                    //data
6984          camera_memory_t *buffer = mGetMemory(-1,
6985                  buffer_len, 1, mCallbackCookie);
6986          if ( NULL == buffer ) {
6987              LOGE("Not enough memory for data");
6988              return NO_MEMORY;
6989          }
6990  
6991          int *pData = (int *)buffer->data;
6992          if (pData == NULL) {
6993              LOGE("memory data ptr is NULL");
6994              buffer->release(buffer);
6995              return UNKNOWN_ERROR;
6996          }
6997  
6998          pData[0] = QCAMERA_METADATA_LED_CALIB;
6999          pData[1] = (int)data_len;
7000          pData[2] = value;
7001  
7002          qcamera_callback_argm_t cbArg;
7003          memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
7004          cbArg.cb_type = QCAMERA_DATA_CALLBACK;
7005          cbArg.msg_type = CAMERA_MSG_META_DATA;
7006          cbArg.data = buffer;
7007          cbArg.user_data = buffer;
7008          cbArg.cookie = this;
7009          cbArg.release_cb = releaseCameraMemory;
7010          int32_t rc = m_cbNotifier.notifyCallback(cbArg);
7011          if (rc != NO_ERROR) {
7012              LOGE("fail sending notification");
7013              buffer->release(buffer);
7014          }
7015      }
7016  #else
7017      (void)value;  // unused
7018  #endif
7019      return rc;
7020  }
7021  
7022  
7023  /*===========================================================================
7024   * FUNCTION   : transAwbMetaToParams
7025   *
7026   * DESCRIPTION: translate awb params from metadata callback to QCameraParametersIntf
7027   *
7028   * PARAMETERS :
7029   *   @awb_params : awb params from metadata callback
7030   *
7031   * RETURN     : int32_t type of status
7032   *              NO_ERROR  -- success
7033   *              none-zero failure code
7034   *==========================================================================*/
transAwbMetaToParams(cam_awb_params_t & awb_params)7035  int32_t QCamera2HardwareInterface::transAwbMetaToParams(cam_awb_params_t &awb_params)
7036  {
7037      mParameters.updateAWBParams(awb_params);
7038      return NO_ERROR;
7039  }
7040  
7041  /*===========================================================================
7042   * FUNCTION   : processPrepSnapshotDone
7043   *
7044   * DESCRIPTION: process prep snapshot done event
7045   *
7046   * PARAMETERS :
7047   *   @prep_snapshot_state  : state of prepare snapshot done. In other words,
7048   *                           i.e. whether need future frames for capture.
7049   *
7050   * RETURN     : int32_t type of status
7051   *              NO_ERROR  -- success
7052   *              none-zero failure code
7053   *==========================================================================*/
processPrepSnapshotDoneEvent(cam_prep_snapshot_state_t prep_snapshot_state)7054  int32_t QCamera2HardwareInterface::processPrepSnapshotDoneEvent(
7055                          cam_prep_snapshot_state_t prep_snapshot_state)
7056  {
7057      int32_t ret = NO_ERROR;
7058      LOGI("[KPI Perf]: Received PREPARE SANSPHOT Done event state = %d",
7059              prep_snapshot_state);
7060      if (m_channels[QCAMERA_CH_TYPE_ZSL] &&
7061          prep_snapshot_state == NEED_FUTURE_FRAME) {
7062          LOGH("already handled in mm-camera-intf, no ops here");
7063          if (isRetroPicture()) {
7064              mParameters.setAecLock("true");
7065              mParameters.commitParameters();
7066              m_bLedAfAecLock = TRUE;
7067          }
7068      }
7069      return ret;
7070  }
7071  
7072  /*===========================================================================
7073   * FUNCTION   : processASDUpdate
7074   *
7075   * DESCRIPTION: process ASD update event
7076   *
7077   * PARAMETERS :
7078   *   @scene: selected scene mode
7079   *
7080   * RETURN     : int32_t type of status
7081   *              NO_ERROR  -- success
7082   *              none-zero failure code
7083   *==========================================================================*/
processASDUpdate(__unused cam_asd_decision_t asd_decision)7084  int32_t QCamera2HardwareInterface::processASDUpdate(
7085          __unused cam_asd_decision_t asd_decision)
7086  {
7087  #ifndef VANILLA_HAL
7088      if ( msgTypeEnabled(CAMERA_MSG_META_DATA) ) {
7089          size_t data_len = sizeof(cam_auto_scene_t);
7090          size_t buffer_len = 1 *sizeof(int)       //meta type
7091                  + 1 *sizeof(int)       //data len
7092                  + data_len;            //data
7093          camera_memory_t *asdBuffer = mGetMemory(-1,
7094                  buffer_len, 1, mCallbackCookie);
7095          if ( NULL == asdBuffer ) {
7096              LOGE("Not enough memory for histogram data");
7097              return NO_MEMORY;
7098          }
7099  
7100          int *pASDData = (int *)asdBuffer->data;
7101          if (pASDData == NULL) {
7102              LOGE("memory data ptr is NULL");
7103              return UNKNOWN_ERROR;
7104          }
7105  
7106          pASDData[0] = CAMERA_META_DATA_ASD;
7107          pASDData[1] = (int)data_len;
7108          pASDData[2] = asd_decision.detected_scene;
7109  
7110          qcamera_callback_argm_t cbArg;
7111          memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
7112          cbArg.cb_type = QCAMERA_DATA_CALLBACK;
7113          cbArg.msg_type = CAMERA_MSG_META_DATA;
7114          cbArg.data = asdBuffer;
7115          cbArg.user_data = asdBuffer;
7116          cbArg.cookie = this;
7117          cbArg.release_cb = releaseCameraMemory;
7118          int32_t rc = m_cbNotifier.notifyCallback(cbArg);
7119          if (rc != NO_ERROR) {
7120              LOGE("fail sending notification");
7121              asdBuffer->release(asdBuffer);
7122          }
7123      }
7124  #endif
7125      return NO_ERROR;
7126  }
7127  
7128  /*===========================================================================
7129   * FUNCTION   : processJpegNotify
7130   *
7131   * DESCRIPTION: process jpeg event
7132   *
7133   * PARAMETERS :
7134   *   @jpeg_evt: ptr to jpeg event payload
7135   *
7136   * RETURN     : int32_t type of status
7137   *              NO_ERROR  -- success
7138   *              none-zero failure code
7139   *==========================================================================*/
processJpegNotify(qcamera_jpeg_evt_payload_t * jpeg_evt)7140  int32_t QCamera2HardwareInterface::processJpegNotify(qcamera_jpeg_evt_payload_t *jpeg_evt)
7141  {
7142      return m_postprocessor.processJpegEvt(jpeg_evt);
7143  }
7144  
7145  
7146  /*===========================================================================
7147   * FUNCTION   : processDualCamFovControl
7148   *
7149   * DESCRIPTION: Based on the result collected from FOV control-
7150   *              1. Switch the master camera if needed
7151   *              2. Toggle the Low Power Mode for slave camera
7152   *
7153   * PARAMETERS : none
7154   *
7155   * RETURN     : none
7156   *==========================================================================*/
processDualCamFovControl()7157  void QCamera2HardwareInterface::processDualCamFovControl()
7158  {
7159     uint32_t activeCameras;
7160     bool bundledSnapshot;
7161     fov_control_result_t fovControlResult;
7162     cam_sync_type_t camMasterSnapshot;
7163  
7164      if (!isDualCamera()) {
7165          return;
7166      }
7167  
7168      fovControlResult = m_pFovControl->getFovControlResult();
7169  
7170      if (fovControlResult.isValid) {
7171          activeCameras = fovControlResult.activeCameras;
7172          bundledSnapshot = fovControlResult.snapshotPostProcess;
7173          camMasterSnapshot = fovControlResult.camMasterPreview;
7174  
7175          processCameraControl(activeCameras, bundledSnapshot);
7176          switchCameraCb(fovControlResult.camMasterPreview);
7177      }
7178  }
7179  
7180  /*===========================================================================
7181   * FUNCTION   : processCameraControl
7182   *
7183   * DESCRIPTION: Suspend and resume camera
7184   *
7185   * PARAMETERS :
7186   *
7187   * RETURN     : int32_t type of status
7188   *              NO_ERROR  -- success
7189   *              none-zero failure code
7190   *==========================================================================*/
processCameraControl(uint32_t activeCameras,bool bundledSnapshot)7191  int32_t QCamera2HardwareInterface::processCameraControl(
7192          uint32_t activeCameras,
7193          bool     bundledSnapshot)
7194  {
7195      int32_t ret = NO_ERROR;
7196  
7197      //Update camera status to internal channel
7198      for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
7199          if (m_channels[i] != NULL && m_channels[i]->isDualChannel()) {
7200              ret = m_channels[i]->processCameraControl(activeCameras, bundledSnapshot);
7201              if (ret != NO_ERROR) {
7202                  LOGE("Channel Switch Failed");
7203                  break;
7204              }
7205          }
7206      }
7207  
7208      if ((activeCameras != mActiveCameras) ||
7209              ((activeCameras == MM_CAMERA_DUAL_CAM) && (bundledSnapshot != mBundledSnapshot))) {
7210  
7211          if (activeCameras != mActiveCameras) {
7212              //Set camera controls to parameter and back-end
7213              ret = mParameters.setCameraControls(activeCameras);
7214          }
7215  
7216          mParameters.setBundledSnapshot(bundledSnapshot);
7217          mParameters.setNumOfSnapshot();
7218  
7219          LOGH("mActiveCameras = %d to %d, bundledSnapshot = %d to %d",
7220                  mActiveCameras, activeCameras, mBundledSnapshot, bundledSnapshot);
7221          mActiveCameras   = activeCameras;
7222          mBundledSnapshot = bundledSnapshot;
7223      }
7224  
7225      return ret;
7226  }
7227  
7228  /*===========================================================================
7229   * FUNCTION   : switchCameraCb
7230   *
7231   * DESCRIPTION: switch camera's in case of dual camera
7232   *
7233   * PARAMETERS :
7234   * @camMaster : Master camera
7235   *
7236   * RETURN     : int32_t type of status
7237   *              NO_ERROR  -- success
7238   *              none-zero failure code
7239   *==========================================================================*/
switchCameraCb(uint32_t camMaster)7240  int32_t QCamera2HardwareInterface::switchCameraCb(uint32_t camMaster)
7241  {
7242      int32_t ret = NO_ERROR;
7243  
7244      if (mActiveCameras & camMaster) {
7245          for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
7246              if (m_channels[i] != NULL && m_channels[i]->isDualChannel()) {
7247                  ret = m_channels[i]->switchChannelCb(camMaster);
7248                  if (ret != NO_ERROR) {
7249                      LOGE("Channel Switch Failed");
7250                      break;
7251                  }
7252              }
7253          }
7254  
7255          if (mMasterCamera != camMaster) {
7256              if (ret == NO_ERROR) {
7257                  //Trigger Event to modules to update Master info
7258                  mParameters.setSwitchCamera(camMaster);
7259              }
7260          }
7261          // Update master camera
7262          mMasterCamera = camMaster;
7263      }
7264  
7265      return ret;
7266  }
7267  
7268  /*===========================================================================
7269   * FUNCTION   : lockAPI
7270   *
7271   * DESCRIPTION: lock to process API
7272   *
7273   * PARAMETERS : none
7274   *
7275   * RETURN     : none
7276   *==========================================================================*/
lockAPI()7277  void QCamera2HardwareInterface::lockAPI()
7278  {
7279      pthread_mutex_lock(&m_lock);
7280  }
7281  
7282  /*===========================================================================
7283   * FUNCTION   : waitAPIResult
7284   *
7285   * DESCRIPTION: wait for API result coming back. This is a blocking call, it will
7286   *              return only cerntain API event type arrives
7287   *
7288   * PARAMETERS :
7289   *   @api_evt : API event type
7290   *
7291   * RETURN     : none
7292   *==========================================================================*/
waitAPIResult(qcamera_sm_evt_enum_t api_evt,qcamera_api_result_t * apiResult)7293  void QCamera2HardwareInterface::waitAPIResult(qcamera_sm_evt_enum_t api_evt,
7294          qcamera_api_result_t *apiResult)
7295  {
7296      LOGD("wait for API result of evt (%d)", api_evt);
7297      int resultReceived = 0;
7298      while  (!resultReceived) {
7299          pthread_cond_wait(&m_cond, &m_lock);
7300          if (m_apiResultList != NULL) {
7301              api_result_list *apiResultList = m_apiResultList;
7302              api_result_list *apiResultListPrevious = m_apiResultList;
7303              while (apiResultList != NULL) {
7304                  if (apiResultList->result.request_api == api_evt) {
7305                      resultReceived = 1;
7306                      *apiResult = apiResultList->result;
7307                      apiResultListPrevious->next = apiResultList->next;
7308                      if (apiResultList == m_apiResultList) {
7309                          m_apiResultList = apiResultList->next;
7310                      }
7311                      free(apiResultList);
7312                      break;
7313                  }
7314                  else {
7315                      apiResultListPrevious = apiResultList;
7316                      apiResultList = apiResultList->next;
7317                  }
7318              }
7319          }
7320      }
7321      LOGD("return (%d) from API result wait for evt (%d)",
7322             apiResult->status, api_evt);
7323  }
7324  
7325  
7326  /*===========================================================================
7327   * FUNCTION   : unlockAPI
7328   *
7329   * DESCRIPTION: API processing is done, unlock
7330   *
7331   * PARAMETERS : none
7332   *
7333   * RETURN     : none
7334   *==========================================================================*/
unlockAPI()7335  void QCamera2HardwareInterface::unlockAPI()
7336  {
7337      pthread_mutex_unlock(&m_lock);
7338  }
7339  
7340  /*===========================================================================
7341   * FUNCTION   : signalAPIResult
7342   *
7343   * DESCRIPTION: signal condition viarable that cerntain API event type arrives
7344   *
7345   * PARAMETERS :
7346   *   @result  : API result
7347   *
7348   * RETURN     : none
7349   *==========================================================================*/
signalAPIResult(qcamera_api_result_t * result)7350  void QCamera2HardwareInterface::signalAPIResult(qcamera_api_result_t *result)
7351  {
7352  
7353      pthread_mutex_lock(&m_lock);
7354      api_result_list *apiResult = (api_result_list *)malloc(sizeof(api_result_list));
7355      if (apiResult == NULL) {
7356          LOGE("ERROR: malloc for api result failed, Result will not be sent");
7357          goto malloc_failed;
7358      }
7359      apiResult->result = *result;
7360      apiResult->next = NULL;
7361      if (m_apiResultList == NULL) m_apiResultList = apiResult;
7362      else {
7363          api_result_list *apiResultList = m_apiResultList;
7364          while(apiResultList->next != NULL) apiResultList = apiResultList->next;
7365          apiResultList->next = apiResult;
7366      }
7367  malloc_failed:
7368      pthread_cond_broadcast(&m_cond);
7369      pthread_mutex_unlock(&m_lock);
7370  }
7371  
7372  /*===========================================================================
7373   * FUNCTION   : signalEvtResult
7374   *
7375   * DESCRIPTION: signal condition variable that certain event was processed
7376   *
7377   * PARAMETERS :
7378   *   @result  : Event result
7379   *
7380   * RETURN     : none
7381   *==========================================================================*/
signalEvtResult(qcamera_api_result_t * result)7382  void QCamera2HardwareInterface::signalEvtResult(qcamera_api_result_t *result)
7383  {
7384      pthread_mutex_lock(&m_evtLock);
7385      m_evtResult = *result;
7386      pthread_cond_signal(&m_evtCond);
7387      pthread_mutex_unlock(&m_evtLock);
7388  }
7389  
prepareRawStream(QCameraChannel * curChannel)7390  int32_t QCamera2HardwareInterface::prepareRawStream(QCameraChannel *curChannel)
7391  {
7392      int32_t rc = NO_ERROR;
7393      cam_dimension_t str_dim,max_dim;
7394      QCameraChannel *pChannel;
7395  
7396      max_dim.width = 0;
7397      max_dim.height = 0;
7398  
7399      for (int j = 0; j < QCAMERA_CH_TYPE_MAX; j++) {
7400          if (m_channels[j] != NULL) {
7401              pChannel = m_channels[j];
7402              for (uint8_t i = 0; i < pChannel->getNumOfStreams(); i++) {
7403                  QCameraStream *pStream = pChannel->getStreamByIndex(i);
7404                  if (pStream != NULL) {
7405                      if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA))
7406                              || (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW))) {
7407                          continue;
7408                      }
7409                      pStream->getFrameDimension(str_dim);
7410                      if (str_dim.width > max_dim.width) {
7411                          max_dim.width = str_dim.width;
7412                      }
7413                      if (str_dim.height > max_dim.height) {
7414                          max_dim.height = str_dim.height;
7415                      }
7416                  }
7417              }
7418          }
7419      }
7420  
7421      for (uint8_t i = 0; i < curChannel->getNumOfStreams(); i++) {
7422          QCameraStream *pStream = curChannel->getStreamByIndex(i);
7423          if (pStream != NULL) {
7424              if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA))
7425                      || (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW))) {
7426                  continue;
7427              }
7428              pStream->getFrameDimension(str_dim);
7429              if (str_dim.width > max_dim.width) {
7430                  max_dim.width = str_dim.width;
7431              }
7432              if (str_dim.height > max_dim.height) {
7433                  max_dim.height = str_dim.height;
7434              }
7435          }
7436      }
7437      rc = mParameters.updateRAW(max_dim);
7438      return rc;
7439  }
7440  
7441  /*===========================================================================
7442   * FUNCTION   : getPaddingInfo
7443   *
7444   * DESCRIPTION: calculate padding per stream
7445   *
7446   * PARAMETERS :
7447   *   @streamType  : type of stream to be added
7448   *   @padding_info : Padding info. Output
7449   *
7450   * RETURN     : int32_t type of status
7451   *              NO_ERROR  -- success
7452   *              none-zero failure code
7453   *==========================================================================*/
getPaddingInfo(cam_stream_type_t streamType,cam_padding_info_t * padding_info)7454  int32_t QCamera2HardwareInterface::getPaddingInfo(cam_stream_type_t streamType,
7455          cam_padding_info_t *padding_info)
7456  {
7457      int32_t rc = NO_ERROR;
7458      if (streamType == CAM_STREAM_TYPE_ANALYSIS) {
7459          cam_analysis_info_t analysisInfo;
7460          cam_feature_mask_t featureMask;
7461  
7462          featureMask = 0;
7463          mParameters.getStreamPpMask(CAM_STREAM_TYPE_ANALYSIS, featureMask);
7464          rc = mParameters.getAnalysisInfo(
7465                  ((mParameters.getRecordingHintValue() == true) &&
7466                   mParameters.fdModeInVideo()),
7467                  featureMask,
7468                  &analysisInfo);
7469          if (rc != NO_ERROR) {
7470              LOGE("getAnalysisInfo failed, ret = %d", rc);
7471              return rc;
7472          }
7473  
7474          *padding_info = analysisInfo.analysis_padding_info;
7475      } else {
7476          *padding_info =
7477                  gCamCapability[mCameraId]->padding_info;
7478          if (streamType == CAM_STREAM_TYPE_PREVIEW || streamType == CAM_STREAM_TYPE_POSTVIEW) {
7479              padding_info->width_padding = mSurfaceStridePadding;
7480              padding_info->height_padding = CAM_PAD_TO_2;
7481          }
7482          if((!needReprocess())
7483                  || (streamType != CAM_STREAM_TYPE_SNAPSHOT)
7484                  || (!mParameters.isLLNoiseEnabled())) {
7485              padding_info->offset_info.offset_x = 0;
7486              padding_info->offset_info.offset_y = 0;
7487          }
7488      }
7489      return rc;
7490  }
7491  
7492  /*===========================================================================
7493   * FUNCTION   : addStreamToChannel
7494   *
7495   * DESCRIPTION: add a stream into a channel
7496   *
7497   * PARAMETERS :
7498   *   @pChannel   : ptr to channel obj
7499   *   @streamType : type of stream to be added
7500   *   @streamCB   : callback of stream
7501   *   @userData   : user data ptr to callback
7502   *
7503   * RETURN     : int32_t type of status
7504   *              NO_ERROR  -- success
7505   *              none-zero failure code
7506   *==========================================================================*/
addStreamToChannel(QCameraChannel * pChannel,cam_stream_type_t streamType,stream_cb_routine streamCB,void * userData)7507  int32_t QCamera2HardwareInterface::addStreamToChannel(QCameraChannel *pChannel,
7508                                                        cam_stream_type_t streamType,
7509                                                        stream_cb_routine streamCB,
7510                                                        void *userData)
7511  {
7512      int32_t rc = NO_ERROR;
7513      QCameraHeapMemory *pStreamInfo = NULL;
7514      uint32_t cam_type = MM_CAMERA_TYPE_MAIN;
7515      bool needAuxStream = FALSE;
7516  
7517      if (streamType == CAM_STREAM_TYPE_RAW) {
7518          prepareRawStream(pChannel);
7519      }
7520  
7521      if (isDualCamera()) {
7522          if (!((mParameters.isDCmAsymmetricSnapMode()) &&
7523                  (streamType == CAM_STREAM_TYPE_SNAPSHOT))) {
7524              cam_type |= MM_CAMERA_TYPE_AUX;
7525          } else {
7526              needAuxStream = TRUE;
7527          }
7528      }
7529  
7530      pStreamInfo = allocateStreamInfoBuf(streamType,
7531              getStreamRefCount(streamType, cam_type), cam_type);
7532      if (pStreamInfo == NULL) {
7533          LOGE("no mem for stream info buf");
7534          return NO_MEMORY;
7535      }
7536  
7537      bool bDynAllocBuf = false;
7538      if (isZSLMode() && streamType == CAM_STREAM_TYPE_SNAPSHOT) {
7539          bDynAllocBuf = true;
7540      }
7541  
7542      cam_padding_info_t padding_info;
7543      getPaddingInfo(streamType, &padding_info);
7544  
7545      bool deferAllocation = needDeferred(streamType);
7546      LOGD("deferAllocation = %d bDynAllocBuf = %d, stream type = %d",
7547              deferAllocation, bDynAllocBuf, streamType);
7548      rc = pChannel->addStream(*this,
7549              pStreamInfo, NULL, &padding_info,
7550              streamCB, userData, bDynAllocBuf,
7551              deferAllocation, ROTATE_0, cam_type);
7552  
7553      if (rc != NO_ERROR) {
7554          LOGE("add stream type (%d) cam = %d failed, ret = %d",
7555                 streamType, cam_type, rc);
7556          return rc;
7557      }
7558  
7559      /*Add stream for Asymmetric dual camera use case*/
7560      if (needAuxStream) {
7561          cam_type = MM_CAMERA_TYPE_AUX;
7562          pStreamInfo = allocateStreamInfoBuf(streamType,
7563                  getStreamRefCount(streamType, cam_type), cam_type);
7564          if (pStreamInfo == NULL) {
7565              LOGE("no mem for stream info buf");
7566              return NO_MEMORY;
7567          }
7568          rc = pChannel->addStream(*this,
7569                  pStreamInfo, NULL, &padding_info,
7570                  streamCB, userData, bDynAllocBuf,
7571                  deferAllocation, ROTATE_0, cam_type);
7572          if (rc != NO_ERROR) {
7573              LOGE("add stream type (%d) cam = %d failed, ret = %d",
7574                     streamType, cam_type, rc);
7575              return rc;
7576          }
7577      }
7578      return rc;
7579  }
7580  
7581  /*===========================================================================
7582   * FUNCTION   : addPreviewChannel
7583   *
7584   * DESCRIPTION: add a preview channel that contains a preview stream
7585   *
7586   * PARAMETERS : none
7587   *
7588   * RETURN     : int32_t type of status
7589   *              NO_ERROR  -- success
7590   *              none-zero failure code
7591   *==========================================================================*/
addPreviewChannel()7592  int32_t QCamera2HardwareInterface::addPreviewChannel()
7593  {
7594      int32_t rc = NO_ERROR;
7595      QCameraChannel *pChannel = NULL;
7596      char value[PROPERTY_VALUE_MAX];
7597      bool raw_yuv = false;
7598  
7599  
7600      if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
7601          // if we had preview channel before, delete it first
7602          delete m_channels[QCAMERA_CH_TYPE_PREVIEW];
7603          m_channels[QCAMERA_CH_TYPE_PREVIEW] = NULL;
7604      }
7605  
7606      uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_PREVIEW);
7607      pChannel = new QCameraChannel(handle, mCameraHandle->ops);
7608      if (NULL == pChannel) {
7609          LOGE("no mem for preview channel");
7610          return NO_MEMORY;
7611      }
7612  
7613      // preview only channel, don't need bundle attr and cb
7614      rc = pChannel->init(NULL, NULL, NULL);
7615      if (rc != NO_ERROR) {
7616          LOGE("init preview channel failed, ret = %d", rc);
7617          delete pChannel;
7618          return rc;
7619      }
7620  
7621      // meta data stream always coexists with preview if applicable
7622      rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
7623              metadata_stream_cb_routine, this);
7624      if (rc != NO_ERROR) {
7625          LOGE("add metadata stream failed, ret = %d", rc);
7626          delete pChannel;
7627          return rc;
7628      }
7629  
7630      if (isRdiMode()) {
7631          rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
7632                  rdi_mode_stream_cb_routine, this);
7633      } else {
7634          if (isNoDisplayMode()) {
7635              rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
7636                      nodisplay_preview_stream_cb_routine, this);
7637          } else {
7638              rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
7639                      preview_stream_cb_routine, this);
7640              if (needSyncCB(CAM_STREAM_TYPE_PREVIEW) == TRUE) {
7641                  pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
7642                          synchronous_stream_cb_routine);
7643              }
7644          }
7645      }
7646  
7647      if (rc != NO_ERROR) {
7648          LOGE("add raw/preview stream failed, ret = %d", rc);
7649          delete pChannel;
7650          return rc;
7651      }
7652  
7653      if (((mParameters.fdModeInVideo())
7654              || (mParameters.getDcrf() == true)
7655              || (mParameters.getRecordingHintValue() != true))
7656              && (!isSecureMode())) {
7657          rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
7658                  NULL, this);
7659          if (rc != NO_ERROR) {
7660              LOGE("add Analysis stream failed, ret = %d", rc);
7661              delete pChannel;
7662              return rc;
7663          }
7664      }
7665  
7666      property_get("persist.camera.raw_yuv", value, "0");
7667      raw_yuv = atoi(value) > 0 ? true : false;
7668      if ( raw_yuv ) {
7669          rc = addStreamToChannel(pChannel,CAM_STREAM_TYPE_RAW,
7670                  preview_raw_stream_cb_routine,this);
7671          if ( rc != NO_ERROR ) {
7672              LOGE("add raw stream failed, ret = %d", __FUNCTION__, rc);
7673              delete pChannel;
7674              return rc;
7675          }
7676      }
7677  
7678      if (rc != NO_ERROR) {
7679          LOGE("add preview stream failed, ret = %d", rc);
7680          delete pChannel;
7681          return rc;
7682      }
7683  
7684      m_channels[QCAMERA_CH_TYPE_PREVIEW] = pChannel;
7685      return rc;
7686  }
7687  
7688  /*===========================================================================
7689   * FUNCTION   : addVideoChannel
7690   *
7691   * DESCRIPTION: add a video channel that contains a video stream
7692   *
7693   * PARAMETERS : none
7694   *
7695   * RETURN     : int32_t type of status
7696   *              NO_ERROR  -- success
7697   *              none-zero failure code
7698   *==========================================================================*/
addVideoChannel()7699  int32_t QCamera2HardwareInterface::addVideoChannel()
7700  {
7701      int32_t rc = NO_ERROR;
7702      QCameraVideoChannel *pChannel = NULL;
7703  
7704      if (m_channels[QCAMERA_CH_TYPE_VIDEO] != NULL) {
7705          // if we had video channel before, delete it first
7706          delete m_channels[QCAMERA_CH_TYPE_VIDEO];
7707          m_channels[QCAMERA_CH_TYPE_VIDEO] = NULL;
7708      }
7709  
7710      uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_VIDEO);
7711      pChannel = new QCameraVideoChannel(handle, mCameraHandle->ops);
7712      if (NULL == pChannel) {
7713          LOGE("no mem for video channel");
7714          return NO_MEMORY;
7715      }
7716  
7717      if (isLowPowerMode()) {
7718          mm_camera_channel_attr_t attr;
7719          memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
7720          attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
7721          attr.look_back = 0; //wait for future frame for liveshot
7722          attr.post_frame_skip = mParameters.getZSLBurstInterval();
7723          attr.water_mark = 1; //hold min buffers possible in Q
7724          attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
7725          rc = pChannel->init(&attr, snapshot_channel_cb_routine, this);
7726      } else {
7727          // preview only channel, don't need bundle attr and cb
7728          rc = pChannel->init(NULL, NULL, NULL);
7729      }
7730  
7731      if (rc != 0) {
7732          LOGE("init video channel failed, ret = %d", rc);
7733          delete pChannel;
7734          return rc;
7735      }
7736  
7737      rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_VIDEO,
7738              video_stream_cb_routine, this);
7739  
7740      if (rc != NO_ERROR) {
7741          LOGE("add video stream failed, ret = %d", rc);
7742          delete pChannel;
7743          return rc;
7744      }
7745  
7746      m_channels[QCAMERA_CH_TYPE_VIDEO] = pChannel;
7747      return rc;
7748  }
7749  
7750  /*===========================================================================
7751   * FUNCTION   : addSnapshotChannel
7752   *
7753   * DESCRIPTION: add a snapshot channel that contains a snapshot stream
7754   *
7755   * PARAMETERS : none
7756   *
7757   * RETURN     : int32_t type of status
7758   *              NO_ERROR  -- success
7759   *              none-zero failure code
7760   * NOTE       : Add this channel for live snapshot usecase. Regular capture will
7761   *              use addCaptureChannel.
7762   *==========================================================================*/
addSnapshotChannel()7763  int32_t QCamera2HardwareInterface::addSnapshotChannel()
7764  {
7765      int32_t rc = NO_ERROR;
7766      QCameraChannel *pChannel = NULL;
7767  
7768      if (m_channels[QCAMERA_CH_TYPE_SNAPSHOT] != NULL) {
7769          // if we had ZSL channel before, delete it first
7770          delete m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
7771          m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = NULL;
7772      }
7773  
7774      uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_SNAPSHOT);
7775      pChannel = new QCameraChannel(handle, mCameraHandle->ops);
7776      if (NULL == pChannel) {
7777          LOGE("no mem for snapshot channel");
7778          return NO_MEMORY;
7779      }
7780  
7781      mm_camera_channel_attr_t attr;
7782      memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
7783      attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
7784      attr.look_back = 0; //wait for future frame for liveshot
7785      attr.post_frame_skip = mParameters.getZSLBurstInterval();
7786      attr.water_mark = 1; //hold min buffers possible in Q
7787      attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
7788      attr.priority = MM_CAMERA_SUPER_BUF_PRIORITY_LOW;
7789      rc = pChannel->init(&attr, snapshot_channel_cb_routine, this);
7790      if (rc != NO_ERROR) {
7791          LOGE("init snapshot channel failed, ret = %d", rc);
7792          delete pChannel;
7793          return rc;
7794      }
7795  
7796      rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
7797              NULL, NULL);
7798      if (rc != NO_ERROR) {
7799          LOGE("add snapshot stream failed, ret = %d", rc);
7800          delete pChannel;
7801          return rc;
7802      }
7803  
7804      m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = pChannel;
7805      return rc;
7806  }
7807  
7808  /*===========================================================================
7809   * FUNCTION   : addRawChannel
7810   *
7811   * DESCRIPTION: add a raw channel that contains a raw image stream
7812   *
7813   * PARAMETERS : none
7814   *
7815   * RETURN     : int32_t type of status
7816   *              NO_ERROR  -- success
7817   *              none-zero failure code
7818   *==========================================================================*/
addRawChannel()7819  int32_t QCamera2HardwareInterface::addRawChannel()
7820  {
7821      int32_t rc = NO_ERROR;
7822      QCameraChannel *pChannel = NULL;
7823  
7824      if (m_channels[QCAMERA_CH_TYPE_RAW] != NULL) {
7825          // if we had raw channel before, delete it first
7826          delete m_channels[QCAMERA_CH_TYPE_RAW];
7827          m_channels[QCAMERA_CH_TYPE_RAW] = NULL;
7828      }
7829  
7830      uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_RAW);
7831      pChannel = new QCameraChannel(handle, mCameraHandle->ops);
7832      if (NULL == pChannel) {
7833          LOGE("no mem for raw channel");
7834          return NO_MEMORY;
7835      }
7836  
7837      if (mParameters.getofflineRAW()) {
7838          mm_camera_channel_attr_t attr;
7839          memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
7840          attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
7841          attr.look_back = mParameters.getZSLBackLookCount();
7842          attr.post_frame_skip = mParameters.getZSLBurstInterval();
7843          attr.water_mark = 1;
7844          attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
7845          rc = pChannel->init(&attr, raw_channel_cb_routine, this);
7846          if (rc != NO_ERROR) {
7847              LOGE("init RAW channel failed, ret = %d", rc);
7848              delete pChannel;
7849              return rc;
7850          }
7851      } else {
7852          rc = pChannel->init(NULL, NULL, NULL);
7853          if (rc != NO_ERROR) {
7854              LOGE("init raw channel failed, ret = %d", rc);
7855              delete pChannel;
7856              return rc;
7857          }
7858      }
7859  
7860      if (!mParameters.isZSLMode()) {
7861          // meta data stream always coexists with snapshot in regular RAW capture case
7862          rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
7863                  metadata_stream_cb_routine, this);
7864          if (rc != NO_ERROR) {
7865              LOGE("add metadata stream failed, ret = %d", rc);
7866              delete pChannel;
7867              return rc;
7868          }
7869      }
7870  
7871      if (mParameters.getofflineRAW()) {
7872          rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
7873                  NULL, this);
7874      } else if(isSecureMode()) {
7875          rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
7876                  secure_stream_cb_routine, this);
7877      } else {
7878          rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
7879                  raw_stream_cb_routine, this);
7880      }
7881      if (rc != NO_ERROR) {
7882          LOGE("add snapshot stream failed, ret = %d", rc);
7883          delete pChannel;
7884          return rc;
7885      }
7886      m_channels[QCAMERA_CH_TYPE_RAW] = pChannel;
7887      return rc;
7888  }
7889  
7890  /*===========================================================================
7891   * FUNCTION   : addZSLChannel
7892   *
7893   * DESCRIPTION: add a ZSL channel that contains a preview stream and
7894   *              a snapshot stream
7895   *
7896   * PARAMETERS : none
7897   *
7898   * RETURN     : int32_t type of status
7899   *              NO_ERROR  -- success
7900   *              none-zero failure code
7901   *==========================================================================*/
addZSLChannel()7902  int32_t QCamera2HardwareInterface::addZSLChannel()
7903  {
7904      int32_t rc = NO_ERROR;
7905      QCameraPicChannel *pChannel = NULL;
7906      char value[PROPERTY_VALUE_MAX];
7907      bool raw_yuv = false;
7908  
7909      if (m_channels[QCAMERA_CH_TYPE_ZSL] != NULL) {
7910          // if we had ZSL channel before, delete it first
7911          delete m_channels[QCAMERA_CH_TYPE_ZSL];
7912          m_channels[QCAMERA_CH_TYPE_ZSL] = NULL;
7913      }
7914  
7915      uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_ZSL);
7916      pChannel = new QCameraPicChannel(handle,
7917                                       mCameraHandle->ops);
7918      if (NULL == pChannel) {
7919          LOGE("no mem for ZSL channel");
7920          return NO_MEMORY;
7921      }
7922  
7923      // ZSL channel, init with bundle attr and cb
7924      mm_camera_channel_attr_t attr;
7925      memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
7926      if (mParameters.isSceneSelectionEnabled()) {
7927          attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
7928      } else {
7929          attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
7930      }
7931      attr.look_back = mParameters.getZSLBackLookCount();
7932      attr.post_frame_skip = mParameters.getZSLBurstInterval();
7933      if (mParameters.isOEMFeatEnabled()) {
7934          LOGD("EDGE SMOOTH frameskip enabled");
7935          attr.post_frame_skip += mParameters.isOEMFeatFrameSkipEnabled();
7936      }
7937      attr.water_mark = mParameters.getZSLQueueDepth();
7938      attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
7939      attr.user_expected_frame_id =
7940          mParameters.isInstantCaptureEnabled() ? (uint8_t)mParameters.getAecFrameBoundValue() : 0;
7941  
7942      //Enabled matched queue
7943      if (isFrameSyncEnabled()) {
7944          LOGH("Enabling frame sync for dual camera, camera Id: %d",
7945                   mCameraId);
7946          attr.enable_frame_sync = 1;
7947      }
7948      rc = pChannel->init(&attr,
7949                          zsl_channel_cb,
7950                          this);
7951      if (rc != 0) {
7952          LOGE("init ZSL channel failed, ret = %d", rc);
7953          delete pChannel;
7954          return rc;
7955      }
7956  
7957      // meta data stream always coexists with preview if applicable
7958      rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
7959              metadata_stream_cb_routine, this);
7960      if (rc != NO_ERROR) {
7961          LOGE("add metadata stream failed, ret = %d", rc);
7962          delete pChannel;
7963          return rc;
7964      }
7965  
7966      if (isNoDisplayMode()) {
7967          rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
7968                  nodisplay_preview_stream_cb_routine, this);
7969      } else {
7970          rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
7971                  preview_stream_cb_routine, this);
7972          if (needSyncCB(CAM_STREAM_TYPE_PREVIEW) == TRUE) {
7973              pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
7974                      synchronous_stream_cb_routine);
7975          }
7976      }
7977      if (rc != NO_ERROR) {
7978          LOGE("add preview stream failed, ret = %d", rc);
7979          delete pChannel;
7980          return rc;
7981      }
7982  
7983      rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
7984              NULL, this);
7985      if (rc != NO_ERROR) {
7986          LOGE("add snapshot stream failed, ret = %d", rc);
7987          delete pChannel;
7988          return rc;
7989      }
7990  
7991      if (!isSecureMode()) {
7992          rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
7993                  NULL, this);
7994          if (rc != NO_ERROR) {
7995              LOGE("add Analysis stream failed, ret = %d", rc);
7996              delete pChannel;
7997              return rc;
7998          }
7999      }
8000  
8001      property_get("persist.camera.raw_yuv", value, "0");
8002      raw_yuv = atoi(value) > 0 ? true : false;
8003      if (raw_yuv) {
8004          rc = addStreamToChannel(pChannel,
8005                                  CAM_STREAM_TYPE_RAW,
8006                                  preview_raw_stream_cb_routine,
8007                                  this);
8008          if (rc != NO_ERROR) {
8009              LOGE("add raw stream failed, ret = %d", rc);
8010              delete pChannel;
8011              return rc;
8012          }
8013      }
8014  
8015      m_channels[QCAMERA_CH_TYPE_ZSL] = pChannel;
8016      return rc;
8017  }
8018  
8019  /*===========================================================================
8020   * FUNCTION   : addCaptureChannel
8021   *
8022   * DESCRIPTION: add a capture channel that contains a snapshot stream
8023   *              and a postview stream
8024   *
8025   * PARAMETERS : none
8026   *
8027   * RETURN     : int32_t type of status
8028   *              NO_ERROR  -- success
8029   *              none-zero failure code
8030   * NOTE       : Add this channel for regular capture usecase.
8031   *              For Live snapshot usecase, use addSnapshotChannel.
8032   *==========================================================================*/
addCaptureChannel()8033  int32_t QCamera2HardwareInterface::addCaptureChannel()
8034  {
8035      int32_t rc = NO_ERROR;
8036      QCameraPicChannel *pChannel = NULL;
8037      char value[PROPERTY_VALUE_MAX];
8038      bool raw_yuv = false;
8039  
8040      if (m_channels[QCAMERA_CH_TYPE_CAPTURE] != NULL) {
8041          delete m_channels[QCAMERA_CH_TYPE_CAPTURE];
8042          m_channels[QCAMERA_CH_TYPE_CAPTURE] = NULL;
8043      }
8044  
8045      uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_CAPTURE);
8046      pChannel = new QCameraPicChannel(handle, mCameraHandle->ops);
8047      if (NULL == pChannel) {
8048          LOGE("no mem for capture channel");
8049          return NO_MEMORY;
8050      }
8051  
8052      // Capture channel, only need snapshot and postview streams start together
8053      mm_camera_channel_attr_t attr;
8054      memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
8055      if ( mLongshotEnabled ) {
8056          attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
8057          attr.look_back = mParameters.getZSLBackLookCount();
8058          attr.water_mark = mParameters.getZSLQueueDepth();
8059      } else {
8060          attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
8061      }
8062      attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
8063  
8064      rc = pChannel->init(&attr,
8065                          capture_channel_cb_routine,
8066                          this);
8067      if (rc != NO_ERROR) {
8068          LOGE("init capture channel failed, ret = %d", rc);
8069          delete pChannel;
8070          return rc;
8071      }
8072  
8073      // meta data stream always coexists with snapshot in regular capture case
8074      rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
8075              metadata_stream_cb_routine, this);
8076      if (rc != NO_ERROR) {
8077          LOGE("add metadata stream failed, ret = %d", rc);
8078          delete pChannel;
8079          return rc;
8080      }
8081  
8082      if (mLongshotEnabled) {
8083          rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
8084                  preview_stream_cb_routine, this);
8085          if (rc != NO_ERROR) {
8086              LOGE("add preview stream failed, ret = %d", rc);
8087              delete pChannel;
8088              return rc;
8089          }
8090          if (needSyncCB(CAM_STREAM_TYPE_PREVIEW) == TRUE) {
8091              pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
8092                      synchronous_stream_cb_routine);
8093          }
8094      //Not adding the postview stream to the capture channel if Quadra CFA is enabled.
8095      } else if (!mParameters.getQuadraCfa()) {
8096          rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_POSTVIEW,
8097                                  NULL, this);
8098          if (rc != NO_ERROR) {
8099              LOGE("add postview stream failed, ret = %d", rc);
8100              delete pChannel;
8101              return rc;
8102          }
8103      }
8104  
8105      if (!mParameters.getofflineRAW()) {
8106          rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
8107                  NULL, this);
8108          if (rc != NO_ERROR) {
8109              LOGE("add snapshot stream failed, ret = %d", rc);
8110              delete pChannel;
8111              return rc;
8112          }
8113      }
8114  
8115      stream_cb_routine stream_cb = NULL;
8116      property_get("persist.camera.raw_yuv", value, "0");
8117      raw_yuv = atoi(value) > 0 ? true : false;
8118  
8119      if (raw_yuv) {
8120          stream_cb = snapshot_raw_stream_cb_routine;
8121      }
8122  
8123      if ((raw_yuv) || (mParameters.getofflineRAW())) {
8124          rc = addStreamToChannel(pChannel,
8125                  CAM_STREAM_TYPE_RAW, stream_cb, this);
8126          if (rc != NO_ERROR) {
8127              LOGE("add raw stream failed, ret = %d", rc);
8128              delete pChannel;
8129              return rc;
8130          }
8131      }
8132  
8133      m_channels[QCAMERA_CH_TYPE_CAPTURE] = pChannel;
8134      return rc;
8135  }
8136  
8137  /*===========================================================================
8138   * FUNCTION   : addMetaDataChannel
8139   *
8140   * DESCRIPTION: add a meta data channel that contains a metadata stream
8141   *
8142   * PARAMETERS : none
8143   *
8144   * RETURN     : int32_t type of status
8145   *              NO_ERROR  -- success
8146   *              none-zero failure code
8147   *==========================================================================*/
addMetaDataChannel()8148  int32_t QCamera2HardwareInterface::addMetaDataChannel()
8149  {
8150      int32_t rc = NO_ERROR;
8151      QCameraChannel *pChannel = NULL;
8152  
8153      if (m_channels[QCAMERA_CH_TYPE_METADATA] != NULL) {
8154          delete m_channels[QCAMERA_CH_TYPE_METADATA];
8155          m_channels[QCAMERA_CH_TYPE_METADATA] = NULL;
8156      }
8157  
8158      uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_METADATA);
8159      pChannel = new QCameraChannel(handle, mCameraHandle->ops);
8160      if (NULL == pChannel) {
8161          LOGE("no mem for metadata channel");
8162          return NO_MEMORY;
8163      }
8164  
8165      rc = pChannel->init(NULL,
8166                          NULL,
8167                          NULL);
8168      if (rc != NO_ERROR) {
8169          LOGE("init metadata channel failed, ret = %d", rc);
8170          delete pChannel;
8171          return rc;
8172      }
8173  
8174      rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
8175              metadata_stream_cb_routine, this);
8176      if (rc != NO_ERROR) {
8177          LOGE("add metadata stream failed, ret = %d", rc);
8178          delete pChannel;
8179          return rc;
8180      }
8181  
8182      m_channels[QCAMERA_CH_TYPE_METADATA] = pChannel;
8183      return rc;
8184  }
8185  
8186  /*===========================================================================
8187   * FUNCTION   : addCallbackChannel
8188   *
8189   * DESCRIPTION: add a callback channel that contains a callback stream
8190   *
8191   * PARAMETERS : none
8192   *
8193   * RETURN     : int32_t type of status
8194   *              NO_ERROR  -- success
8195   *              none-zero failure code
8196   *==========================================================================*/
addCallbackChannel()8197  int32_t QCamera2HardwareInterface::addCallbackChannel()
8198  {
8199      int32_t rc = NO_ERROR;
8200      QCameraChannel *pChannel = NULL;
8201  
8202      if (m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL) {
8203          delete m_channels[QCAMERA_CH_TYPE_CALLBACK];
8204          m_channels[QCAMERA_CH_TYPE_CALLBACK] = NULL;
8205      }
8206  
8207      uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_CALLBACK);
8208      pChannel = new QCameraChannel(handle, mCameraHandle->ops);
8209      if (NULL == pChannel) {
8210          LOGE("no mem for callback channel");
8211          return NO_MEMORY;
8212      }
8213  
8214      rc = pChannel->init(NULL, NULL, this);
8215      if (rc != NO_ERROR) {
8216          LOGE("init callback channel failed, ret = %d",
8217                   rc);
8218          delete pChannel;
8219          return rc;
8220      }
8221  
8222      rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_CALLBACK,
8223              callback_stream_cb_routine, this);
8224      if (rc != NO_ERROR) {
8225          LOGE("add callback stream failed, ret = %d", rc);
8226          delete pChannel;
8227          return rc;
8228      }
8229  
8230      m_channels[QCAMERA_CH_TYPE_CALLBACK] = pChannel;
8231      return rc;
8232  }
8233  
8234  
8235  /*===========================================================================
8236   * FUNCTION   : addAnalysisChannel
8237   *
8238   * DESCRIPTION: add a analysis channel that contains a analysis stream
8239   *
8240   * PARAMETERS : none
8241   *
8242   * RETURN     : int32_t type of status
8243   *              NO_ERROR  -- success
8244   *              none-zero failure code
8245   *==========================================================================*/
addAnalysisChannel()8246  int32_t QCamera2HardwareInterface::addAnalysisChannel()
8247  {
8248      int32_t rc = NO_ERROR;
8249      QCameraChannel *pChannel = NULL;
8250  
8251      if (m_channels[QCAMERA_CH_TYPE_ANALYSIS] != NULL) {
8252          delete m_channels[QCAMERA_CH_TYPE_ANALYSIS];
8253          m_channels[QCAMERA_CH_TYPE_ANALYSIS] = NULL;
8254      }
8255  
8256      uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_ANALYSIS);
8257      pChannel = new QCameraChannel(handle, mCameraHandle->ops);
8258      if (NULL == pChannel) {
8259          LOGE("no mem for metadata channel");
8260          return NO_MEMORY;
8261      }
8262  
8263      rc = pChannel->init(NULL, NULL, this);
8264      if (rc != NO_ERROR) {
8265          LOGE("init Analysis channel failed, ret = %d", rc);
8266          delete pChannel;
8267          return rc;
8268      }
8269  
8270      rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
8271              NULL, this);
8272      if (rc != NO_ERROR) {
8273          LOGE("add Analysis stream failed, ret = %d", rc);
8274          delete pChannel;
8275          return rc;
8276      }
8277  
8278      m_channels[QCAMERA_CH_TYPE_ANALYSIS] = pChannel;
8279      return rc;
8280  }
8281  
8282  
8283  /*===========================================================================
8284   * FUNCTION   : getPPConfig
8285   *
8286   * DESCRIPTION: get Post processing configaration data
8287   *
8288   * PARAMETERS :
8289   * @pp config:  pp config structure pointer,
8290   * @curIndex:  current pp channel index
8291   * @multipass: Flag if multipass prcessing enabled.
8292   *
8293   * RETURN     : int32_t type of status
8294   *              NO_ERROR  -- success
8295   *              none-zero failure code
8296   *==========================================================================*/
getPPConfig(cam_pp_feature_config_t & pp_config,int8_t curIndex,bool multipass)8297  int32_t QCamera2HardwareInterface::getPPConfig(cam_pp_feature_config_t &pp_config,
8298          int8_t curIndex, bool multipass)
8299  {
8300      int32_t rc = NO_ERROR;
8301      int32_t feature_set = 0;
8302  
8303      if (multipass) {
8304          LOGW("Multi pass enabled. Total Pass = %d, cur index = %d",
8305                  mParameters.getReprocCount(), curIndex);
8306      }
8307  
8308      LOGH("Supported pproc feature mask = %llx",
8309              gCamCapability[mCameraId]->qcom_supported_feature_mask);
8310      cam_feature_mask_t feature_mask = gCamCapability[mCameraId]->qcom_supported_feature_mask;
8311      int32_t zoomLevel = mParameters.getParmZoomLevel();
8312      uint32_t rotation = mParameters.getJpegRotation();
8313      int32_t effect = mParameters.getEffectValue();
8314  
8315      pp_config.cur_reproc_count = curIndex + 1;
8316      pp_config.total_reproc_count = mParameters.getReprocCount();
8317  
8318      //Checking what feature mask to enable
8319      if (curIndex == 0) {
8320          if (mParameters.getQuadraCfa()) {
8321              feature_set = 2;
8322          } else {
8323              feature_set = 0;
8324          }
8325      } else if (curIndex == 1) {
8326          if (mParameters.getQuadraCfa()) {
8327              feature_set = 0;
8328          } else {
8329              feature_set = 1;
8330          }
8331      }
8332  
8333      switch(feature_set) {
8334          case 0:
8335              //Configure feature mask for first pass of reprocessing
8336              //check if any effects are enabled
8337              if ((CAM_EFFECT_MODE_OFF != effect) &&
8338                  (feature_mask & CAM_QCOM_FEATURE_EFFECT)) {
8339                  pp_config.feature_mask |= CAM_QCOM_FEATURE_EFFECT;
8340                  pp_config.effect = effect;
8341              }
8342  
8343              //check for features that need to be enabled by default like sharpness
8344              //(if supported by hw).
8345              if ((feature_mask & CAM_QCOM_FEATURE_SHARPNESS) &&
8346                  !mParameters.isOptiZoomEnabled()) {
8347                  pp_config.feature_mask |= CAM_QCOM_FEATURE_SHARPNESS;
8348                  pp_config.sharpness = mParameters.getSharpness();
8349              }
8350  
8351              //check if zoom is enabled
8352              if ((zoomLevel > 0) && (feature_mask & CAM_QCOM_FEATURE_CROP)) {
8353                  pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
8354              }
8355  
8356              if (mParameters.isWNREnabled() &&
8357                  (feature_mask & CAM_QCOM_FEATURE_DENOISE2D)) {
8358                  pp_config.feature_mask |= CAM_QCOM_FEATURE_DENOISE2D;
8359                  pp_config.denoise2d.denoise_enable = 1;
8360                  pp_config.denoise2d.process_plates =
8361                          mParameters.getDenoiseProcessPlate(CAM_INTF_PARM_WAVELET_DENOISE);
8362              }
8363  
8364              if (isCACEnabled()) {
8365                  pp_config.feature_mask |= CAM_QCOM_FEATURE_CAC;
8366              }
8367  
8368              //check if rotation is required
8369              if ((feature_mask & CAM_QCOM_FEATURE_ROTATION) && (rotation > 0)) {
8370                  pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION;
8371                  if (rotation == 0) {
8372                      pp_config.rotation = ROTATE_0;
8373                  } else if (rotation == 90) {
8374                      pp_config.rotation = ROTATE_90;
8375                  } else if (rotation == 180) {
8376                      pp_config.rotation = ROTATE_180;
8377                  } else if (rotation == 270) {
8378                      pp_config.rotation = ROTATE_270;
8379                  }
8380              }
8381  
8382              if (mParameters.isHDREnabled()){
8383                  pp_config.feature_mask |= CAM_QCOM_FEATURE_HDR;
8384                  pp_config.hdr_param.hdr_enable = 1;
8385                  pp_config.hdr_param.hdr_need_1x = mParameters.isHDR1xFrameEnabled();
8386                  pp_config.hdr_param.hdr_mode = CAM_HDR_MODE_MULTIFRAME;
8387              } else {
8388                  pp_config.feature_mask &= ~CAM_QCOM_FEATURE_HDR;
8389                  pp_config.hdr_param.hdr_enable = 0;
8390              }
8391  
8392              //check if scaling is enabled
8393              if ((feature_mask & CAM_QCOM_FEATURE_SCALE) &&
8394                  mParameters.isReprocScaleEnabled() &&
8395                  mParameters.isUnderReprocScaling()){
8396                  pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
8397                  mParameters.getPicSizeFromAPK(
8398                          pp_config.scale_param.output_width,
8399                          pp_config.scale_param.output_height);
8400              }
8401  
8402              if(mParameters.isUbiFocusEnabled()) {
8403                  pp_config.feature_mask |= CAM_QCOM_FEATURE_UBIFOCUS;
8404              } else {
8405                  pp_config.feature_mask &= ~CAM_QCOM_FEATURE_UBIFOCUS;
8406              }
8407  
8408              if(mParameters.isUbiRefocus()) {
8409                  pp_config.feature_mask |= CAM_QCOM_FEATURE_REFOCUS;
8410                  pp_config.misc_buf_param.misc_buffer_index = 0;
8411              } else {
8412                  pp_config.feature_mask &= ~CAM_QCOM_FEATURE_REFOCUS;
8413              }
8414  
8415              if(mParameters.isChromaFlashEnabled()) {
8416                  pp_config.feature_mask |= CAM_QCOM_FEATURE_CHROMA_FLASH;
8417                  pp_config.flash_value = CAM_FLASH_ON;
8418              } else {
8419                  pp_config.feature_mask &= ~CAM_QCOM_FEATURE_CHROMA_FLASH;
8420              }
8421  
8422              if(mParameters.isOptiZoomEnabled() && (0 <= zoomLevel)) {
8423                  pp_config.feature_mask |= CAM_QCOM_FEATURE_OPTIZOOM;
8424                  pp_config.zoom_level = (uint8_t) zoomLevel;
8425              } else {
8426                  pp_config.feature_mask &= ~CAM_QCOM_FEATURE_OPTIZOOM;
8427              }
8428  
8429              if (mParameters.getofflineRAW()) {
8430                  pp_config.feature_mask |= CAM_QCOM_FEATURE_RAW_PROCESSING;
8431              }
8432  
8433              if (mParameters.isTruePortraitEnabled()) {
8434                  pp_config.feature_mask |= CAM_QCOM_FEATURE_TRUEPORTRAIT;
8435                  pp_config.misc_buf_param.misc_buffer_index = 0;
8436              } else {
8437                  pp_config.feature_mask &= ~CAM_QCOM_FEATURE_TRUEPORTRAIT;
8438              }
8439  
8440              if(mParameters.isStillMoreEnabled()) {
8441                  pp_config.feature_mask |= CAM_QCOM_FEATURE_STILLMORE;
8442              } else {
8443                  pp_config.feature_mask &= ~CAM_QCOM_FEATURE_STILLMORE;
8444              }
8445  
8446              if (mParameters.isOEMFeatEnabled()) {
8447                  pp_config.feature_mask |= CAM_OEM_FEATURE_1;
8448              }
8449  
8450              if (mParameters.getCDSMode() != CAM_CDS_MODE_OFF) {
8451                  if (feature_mask & CAM_QCOM_FEATURE_DSDN) {
8452                      pp_config.feature_mask |= CAM_QCOM_FEATURE_DSDN;
8453                  } else {
8454                      pp_config.feature_mask |= CAM_QCOM_FEATURE_CDS;
8455                  }
8456              }
8457  
8458              if ((multipass) &&
8459                      (m_postprocessor.getPPChannelCount() > 1)
8460                      && (!mParameters.getQuadraCfa())) {
8461                  pp_config.feature_mask &= ~CAM_QCOM_FEATURE_PP_PASS_2;
8462                  pp_config.feature_mask &= ~CAM_QCOM_FEATURE_ROTATION;
8463                  pp_config.feature_mask &= ~CAM_QCOM_FEATURE_CDS;
8464                  pp_config.feature_mask &= ~CAM_QCOM_FEATURE_DSDN;
8465                  pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
8466              } else {
8467                  pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
8468              }
8469  
8470              cam_dimension_t thumb_src_dim;
8471              cam_dimension_t thumb_dst_dim;
8472              mParameters.getThumbnailSize(&(thumb_dst_dim.width), &(thumb_dst_dim.height));
8473              mParameters.getStreamDimension(CAM_STREAM_TYPE_POSTVIEW,thumb_src_dim);
8474              if ((thumb_dst_dim.width != thumb_src_dim.width) ||
8475                      (thumb_dst_dim.height != thumb_src_dim.height)) {
8476                  if (thumb_dst_dim.width != 0 && thumb_dst_dim.height != 0) {
8477                      pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
8478                  }
8479              }
8480  
8481              break;
8482  
8483          case 1:
8484              //Configure feature mask for second pass of reprocessing
8485              pp_config.feature_mask |= CAM_QCOM_FEATURE_PP_PASS_2;
8486              if ((feature_mask & CAM_QCOM_FEATURE_ROTATION) && (rotation > 0)) {
8487                  pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION;
8488                  if (rotation == 0) {
8489                      pp_config.rotation = ROTATE_0;
8490                  } else if (rotation == 90) {
8491                      pp_config.rotation = ROTATE_90;
8492                  } else if (rotation == 180) {
8493                      pp_config.rotation = ROTATE_180;
8494                  } else if (rotation == 270) {
8495                      pp_config.rotation = ROTATE_270;
8496                  }
8497              }
8498              if (mParameters.getCDSMode() != CAM_CDS_MODE_OFF) {
8499                  if (feature_mask & CAM_QCOM_FEATURE_DSDN) {
8500                      pp_config.feature_mask |= CAM_QCOM_FEATURE_DSDN;
8501                  } else {
8502                      pp_config.feature_mask |= CAM_QCOM_FEATURE_CDS;
8503                  }
8504              }
8505              pp_config.feature_mask &= ~CAM_QCOM_FEATURE_RAW_PROCESSING;
8506              pp_config.feature_mask &= ~CAM_QCOM_FEATURE_METADATA_PROCESSING;
8507              pp_config.feature_mask &= ~CAM_QCOM_FEATURE_METADATA_BYPASS;
8508              break;
8509  
8510          case 2:
8511              //Setting feature for Quadra CFA
8512              pp_config.feature_mask |= CAM_QCOM_FEATURE_QUADRA_CFA;
8513              break;
8514  
8515      }
8516  
8517      LOGH("pproc feature mask set = %llx pass count = %d",
8518          pp_config.feature_mask, curIndex);
8519      return rc;
8520  }
8521  
8522  /*===========================================================================
8523   * FUNCTION   : addReprocChannel
8524   *
8525   * DESCRIPTION: add a reprocess channel that will do reprocess on frames
8526   *              coming from input channel
8527   *
8528   * PARAMETERS :
8529   *   @pInputChannel : ptr to input channel whose frames will be post-processed
8530   *   @cur_channel_index : Current channel index in multipass
8531   *
8532   * RETURN     : Ptr to the newly created channel obj. NULL if failed.
8533   *==========================================================================*/
addReprocChannel(QCameraChannel * pInputChannel,int8_t cur_channel_index)8534  QCameraReprocessChannel *QCamera2HardwareInterface::addReprocChannel(
8535          QCameraChannel *pInputChannel, int8_t cur_channel_index)
8536  {
8537      int32_t rc = NO_ERROR;
8538      QCameraReprocessChannel *pChannel = NULL;
8539      uint32_t burst_cnt = mParameters.getNumOfSnapshots();
8540      uint32_t pHandle = getCamHandleForChannel(QCAMERA_CH_TYPE_REPROCESSING);
8541  
8542      if (pInputChannel == NULL) {
8543          LOGE("input channel obj is NULL");
8544          return NULL;
8545      }
8546  
8547      pChannel = new QCameraReprocessChannel(pHandle, mCameraHandle->ops);
8548      if (NULL == pChannel) {
8549          LOGE("no mem for reprocess channel");
8550          return NULL;
8551      }
8552  
8553      // Capture channel, only need snapshot and postview streams start together
8554      mm_camera_channel_attr_t attr;
8555      memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
8556      attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
8557      attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
8558      rc = pChannel->init(&attr,
8559                          postproc_channel_cb_routine,
8560                          this);
8561      if (rc != NO_ERROR) {
8562          LOGE("init reprocess channel failed, ret = %d", rc);
8563          delete pChannel;
8564          return NULL;
8565      }
8566  
8567      // pp feature config
8568      cam_pp_feature_config_t pp_config;
8569      memset(&pp_config, 0, sizeof(cam_pp_feature_config_t));
8570  
8571      rc = getPPConfig(pp_config, cur_channel_index,
8572              ((mParameters.getReprocCount() > 1) ? TRUE : FALSE));
8573      if (rc != NO_ERROR){
8574          LOGE("Error while creating PP config");
8575          delete pChannel;
8576          return NULL;
8577      }
8578  
8579      uint8_t minStreamBufNum = getBufNumRequired(CAM_STREAM_TYPE_OFFLINE_PROC);
8580  
8581      //WNR and HDR happen inline. No extra buffers needed.
8582      cam_feature_mask_t temp_feature_mask = pp_config.feature_mask;
8583      temp_feature_mask &= ~CAM_QCOM_FEATURE_HDR;
8584      if (temp_feature_mask && mParameters.isHDREnabled()) {
8585          minStreamBufNum = (uint8_t)(1 + mParameters.getNumOfExtraHDRInBufsIfNeeded());
8586      }
8587  
8588      if (mParameters.isStillMoreEnabled()) {
8589          cam_still_more_t stillmore_config = mParameters.getStillMoreSettings();
8590          pp_config.burst_cnt = stillmore_config.burst_count;
8591          LOGH("Stillmore burst %d", pp_config.burst_cnt);
8592  
8593          // getNumOfExtraBuffersForImageProc returns 1 less buffer assuming
8594          // number of capture is already added. In the case of liveshot,
8595          // stillmore burst is 1. This is to account for the premature decrement
8596          if (mParameters.getNumOfExtraBuffersForImageProc() == 0) {
8597              minStreamBufNum += 1;
8598          }
8599      }
8600  
8601      if (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_3) {
8602          minStreamBufNum += mParameters.getReprocCount() - 1;
8603          burst_cnt = mParameters.getReprocCount();
8604          if (cur_channel_index == 0) {
8605              pChannel->setReprocCount(2);
8606          } else {
8607              pChannel->setReprocCount(1);
8608          }
8609      } else {
8610          pChannel->setReprocCount(1);
8611      }
8612  
8613      if (isDualCamera() && mBundledSnapshot) {
8614          minStreamBufNum += 1;
8615      }
8616  
8617      // Add non inplace image lib buffers only when ppproc is present,
8618      // becuase pproc is non inplace and input buffers for img lib
8619      // are output for pproc and this number of extra buffers is required
8620      // If pproc is not there, input buffers for imglib are from snapshot stream
8621      uint8_t imglib_extra_bufs = mParameters.getNumOfExtraBuffersForImageProc();
8622      if (temp_feature_mask && imglib_extra_bufs) {
8623          // 1 is added because getNumOfExtraBuffersForImageProc returns extra
8624          // buffers assuming number of capture is already added
8625          minStreamBufNum = (uint8_t)(minStreamBufNum + imglib_extra_bufs + 1);
8626      }
8627  
8628      //Mask out features that are already processed in snapshot stream.
8629      cam_feature_mask_t snapshot_feature_mask = 0;
8630      mParameters.getStreamPpMask(CAM_STREAM_TYPE_SNAPSHOT, snapshot_feature_mask);
8631  
8632      pp_config.feature_mask &= ~snapshot_feature_mask;
8633      LOGH("Snapshot feature mask: 0x%llx, reproc feature mask: 0x%llx minStreamBufNum = %d",
8634              snapshot_feature_mask, pp_config.feature_mask, minStreamBufNum);
8635  
8636      bool offlineReproc = needOfflineReprocessing();
8637      if (m_postprocessor.mOfflineDataBufs != NULL) {
8638          offlineReproc = TRUE;
8639      }
8640  
8641      cam_padding_info_t paddingInfo = gCamCapability[mCameraId]->padding_info;
8642      paddingInfo.offset_info.offset_x = 0;
8643      paddingInfo.offset_info.offset_y = 0;
8644      rc = pChannel->addReprocStreamsFromSource(*this,
8645                                                pp_config,
8646                                                pInputChannel,
8647                                                minStreamBufNum,
8648                                                burst_cnt,
8649                                                &paddingInfo,
8650                                                mParameters,
8651                                                mLongshotEnabled,
8652                                                offlineReproc);
8653      if (rc != NO_ERROR) {
8654          delete pChannel;
8655          return NULL;
8656      }
8657  
8658      return pChannel;
8659  }
8660  
8661  /*===========================================================================
8662   * FUNCTION   : addOfflineReprocChannel
8663   *
8664   * DESCRIPTION: add a offline reprocess channel contains one reproc stream,
8665   *              that will do reprocess on frames coming from external images
8666   *
8667   * PARAMETERS :
8668   *   @img_config  : offline reporcess image info
8669   *   @pp_feature  : pp feature config
8670   *
8671   * RETURN     : int32_t type of status
8672   *              NO_ERROR  -- success
8673   *              none-zero failure code
8674   *==========================================================================*/
addOfflineReprocChannel(cam_pp_offline_src_config_t & img_config,cam_pp_feature_config_t & pp_feature,stream_cb_routine stream_cb,void * userdata)8675  QCameraReprocessChannel *QCamera2HardwareInterface::addOfflineReprocChannel(
8676                                              cam_pp_offline_src_config_t &img_config,
8677                                              cam_pp_feature_config_t &pp_feature,
8678                                              stream_cb_routine stream_cb,
8679                                              void *userdata)
8680  {
8681      int32_t rc = NO_ERROR;
8682      QCameraReprocessChannel *pChannel = NULL;
8683  
8684      pChannel = new QCameraReprocessChannel(mCameraHandle->camera_handle,
8685                                             mCameraHandle->ops);
8686      if (NULL == pChannel) {
8687          LOGE("no mem for reprocess channel");
8688          return NULL;
8689      }
8690  
8691      rc = pChannel->init(NULL, NULL, NULL);
8692      if (rc != NO_ERROR) {
8693          LOGE("init reprocess channel failed, ret = %d", rc);
8694          delete pChannel;
8695          return NULL;
8696      }
8697  
8698      QCameraHeapMemory *pStreamInfo = allocateStreamInfoBuf(CAM_STREAM_TYPE_OFFLINE_PROC);
8699      if (pStreamInfo == NULL) {
8700          LOGE("no mem for stream info buf");
8701          delete pChannel;
8702          return NULL;
8703      }
8704  
8705      cam_stream_info_t *streamInfoBuf = (cam_stream_info_t *)pStreamInfo->getPtr(0);
8706      memset(streamInfoBuf, 0, sizeof(cam_stream_info_t));
8707      streamInfoBuf->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC;
8708      streamInfoBuf->fmt = img_config.input_fmt;
8709      streamInfoBuf->dim = img_config.input_dim;
8710      streamInfoBuf->buf_planes = img_config.input_buf_planes;
8711      streamInfoBuf->streaming_mode = CAM_STREAMING_MODE_BURST;
8712      streamInfoBuf->num_of_burst = img_config.num_of_bufs;
8713  
8714      streamInfoBuf->reprocess_config.pp_type = CAM_OFFLINE_REPROCESS_TYPE;
8715      streamInfoBuf->reprocess_config.offline = img_config;
8716      streamInfoBuf->reprocess_config.pp_feature_config = pp_feature;
8717      streamInfoBuf->num_bufs = img_config.num_of_bufs;
8718  
8719      rc = pChannel->addStream(*this,
8720              pStreamInfo, NULL,
8721              &gCamCapability[mCameraId]->padding_info,
8722              stream_cb, userdata, false);
8723  
8724      if (rc != NO_ERROR) {
8725          LOGE("add reprocess stream failed, ret = %d", rc);
8726          delete pChannel;
8727          return NULL;
8728      }
8729  
8730      return pChannel;
8731  }
8732  
8733  /*===========================================================================
8734   * FUNCTION   : addChannel
8735   *
8736   * DESCRIPTION: add a channel by its type
8737   *
8738   * PARAMETERS :
8739   *   @ch_type : channel type
8740   *
8741   * RETURN     : int32_t type of status
8742   *              NO_ERROR  -- success
8743   *              none-zero failure code
8744   *==========================================================================*/
addChannel(qcamera_ch_type_enum_t ch_type)8745  int32_t QCamera2HardwareInterface::addChannel(qcamera_ch_type_enum_t ch_type)
8746  {
8747      int32_t rc = UNKNOWN_ERROR;
8748      switch (ch_type) {
8749      case QCAMERA_CH_TYPE_ZSL:
8750          rc = addZSLChannel();
8751          break;
8752      case QCAMERA_CH_TYPE_CAPTURE:
8753          rc = addCaptureChannel();
8754          break;
8755      case QCAMERA_CH_TYPE_PREVIEW:
8756          rc = addPreviewChannel();
8757          break;
8758      case QCAMERA_CH_TYPE_VIDEO:
8759          rc = addVideoChannel();
8760          break;
8761      case QCAMERA_CH_TYPE_SNAPSHOT:
8762          rc = addSnapshotChannel();
8763          break;
8764      case QCAMERA_CH_TYPE_RAW:
8765          rc = addRawChannel();
8766          break;
8767      case QCAMERA_CH_TYPE_METADATA:
8768          rc = addMetaDataChannel();
8769          break;
8770      case QCAMERA_CH_TYPE_CALLBACK:
8771          rc = addCallbackChannel();
8772          break;
8773      case QCAMERA_CH_TYPE_ANALYSIS:
8774          rc = addAnalysisChannel();
8775          break;
8776      default:
8777          break;
8778      }
8779      return rc;
8780  }
8781  
8782  /*===========================================================================
8783   * FUNCTION   : delChannel
8784   *
8785   * DESCRIPTION: delete a channel by its type
8786   *
8787   * PARAMETERS :
8788   *   @ch_type : channel type
8789   *   @destroy : delete context as well
8790   *
8791   * RETURN     : int32_t type of status
8792   *              NO_ERROR  -- success
8793   *              none-zero failure code
8794   *==========================================================================*/
delChannel(qcamera_ch_type_enum_t ch_type,bool destroy)8795  int32_t QCamera2HardwareInterface::delChannel(qcamera_ch_type_enum_t ch_type,
8796                                                bool destroy)
8797  {
8798      if (m_channels[ch_type] != NULL) {
8799          if (destroy) {
8800              delete m_channels[ch_type];
8801              m_channels[ch_type] = NULL;
8802          } else {
8803              m_channels[ch_type]->deleteChannel();
8804          }
8805      }
8806  
8807      return NO_ERROR;
8808  }
8809  
8810  /*===========================================================================
8811   * FUNCTION   : startChannel
8812   *
8813   * DESCRIPTION: start a channel by its type
8814   *
8815   * PARAMETERS :
8816   *   @ch_type : channel type
8817   *
8818   * RETURN     : int32_t type of status
8819   *              NO_ERROR  -- success
8820   *              none-zero failure code
8821   *==========================================================================*/
startChannel(qcamera_ch_type_enum_t ch_type)8822  int32_t QCamera2HardwareInterface::startChannel(qcamera_ch_type_enum_t ch_type)
8823  {
8824      int32_t rc = UNKNOWN_ERROR;
8825      if (m_channels[ch_type] != NULL) {
8826          rc = m_channels[ch_type]->start();
8827      }
8828      return rc;
8829  }
8830  
8831  /*===========================================================================
8832   * FUNCTION   : stopChannel
8833   *
8834   * DESCRIPTION: stop a channel by its type
8835   *
8836   * PARAMETERS :
8837   *   @ch_type : channel type
8838   *
8839   * RETURN     : int32_t type of status
8840   *              NO_ERROR  -- success
8841   *              none-zero failure code
8842   *==========================================================================*/
stopChannel(qcamera_ch_type_enum_t ch_type)8843  int32_t QCamera2HardwareInterface::stopChannel(qcamera_ch_type_enum_t ch_type)
8844  {
8845      int32_t rc = UNKNOWN_ERROR;
8846      if (m_channels[ch_type] != NULL) {
8847          rc = m_channels[ch_type]->stop();
8848      }
8849  
8850      return rc;
8851  }
8852  
8853  /*===========================================================================
8854   * FUNCTION   : preparePreview
8855   *
8856   * DESCRIPTION: add channels needed for preview
8857   *
8858   * PARAMETERS : none
8859   *
8860   * RETURN     : int32_t type of status
8861   *              NO_ERROR  -- success
8862   *              none-zero failure code
8863   *==========================================================================*/
preparePreview()8864  int32_t QCamera2HardwareInterface::preparePreview()
8865  {
8866      ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PREPAREPREVIEW);
8867      int32_t rc = NO_ERROR;
8868  
8869      LOGI("E");
8870      rc = mParameters.setStreamConfigure(false, false, false);
8871      if (rc != NO_ERROR) {
8872          LOGE("setStreamConfigure failed %d", rc);
8873          return rc;
8874      }
8875  
8876      //Trigger deferred job second camera
8877      if (isDualCamera()) {
8878          mParameters.setDeferCamera(CAM_DEFER_START);
8879      }
8880  
8881      if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) {
8882          rc = addChannel(QCAMERA_CH_TYPE_ZSL);
8883          if (rc != NO_ERROR) {
8884              LOGE("failed!! rc = %d", rc);
8885              return rc;
8886          }
8887  
8888          if (mParameters.isUBWCEnabled()) {
8889              cam_format_t fmt;
8890              mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW, fmt);
8891              if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
8892                  rc = addChannel(QCAMERA_CH_TYPE_CALLBACK);
8893                  if (rc != NO_ERROR) {
8894                      delChannel(QCAMERA_CH_TYPE_ZSL);
8895                      LOGE("failed!! rc = %d", rc);
8896                      return rc;
8897                  }
8898              }
8899          }
8900  
8901          if (mParameters.getofflineRAW() && !mParameters.getQuadraCfa()) {
8902              addChannel(QCAMERA_CH_TYPE_RAW);
8903          }
8904      } else if(isSecureMode()) {
8905          if (mParameters.getSecureStreamType() == CAM_STREAM_TYPE_RAW) {
8906              rc = addChannel(QCAMERA_CH_TYPE_RAW);
8907          } else {
8908              rc = addChannel(QCAMERA_CH_TYPE_PREVIEW);
8909          }
8910      } else {
8911          bool recordingHint = mParameters.getRecordingHintValue();
8912          if(!isRdiMode() && recordingHint) {
8913              //stop face detection,longshot,etc if turned ON in Camera mode
8914  #ifndef VANILLA_HAL
8915              int32_t arg; //dummy arg
8916              if (isLongshotEnabled()) {
8917                  sendCommand(CAMERA_CMD_LONGSHOT_OFF, arg, arg);
8918              }
8919              if (mParameters.isFaceDetectionEnabled()
8920                      && (!mParameters.fdModeInVideo())) {
8921                  sendCommand(CAMERA_CMD_STOP_FACE_DETECTION, arg, arg);
8922              }
8923              if (mParameters.isHistogramEnabled()) {
8924                  sendCommand(CAMERA_CMD_HISTOGRAM_OFF, arg, arg);
8925              }
8926  #endif
8927              //Don't create snapshot channel for liveshot, if low power mode is set.
8928              //Use video stream instead.
8929              if (!isLowPowerMode()) {
8930                 rc = addChannel(QCAMERA_CH_TYPE_SNAPSHOT);
8931                 if (rc != NO_ERROR) {
8932                     return rc;
8933                 }
8934              }
8935  
8936              rc = addChannel(QCAMERA_CH_TYPE_VIDEO);
8937              if (rc != NO_ERROR) {
8938                  delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
8939                  LOGE("failed!! rc = %d", rc);
8940                  return rc;
8941              }
8942          }
8943  
8944          rc = addChannel(QCAMERA_CH_TYPE_PREVIEW);
8945          if (!isRdiMode() && (rc != NO_ERROR)) {
8946              if (recordingHint) {
8947                  delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
8948                  delChannel(QCAMERA_CH_TYPE_VIDEO);
8949              }
8950          }
8951  
8952          if (mParameters.isUBWCEnabled() && !recordingHint) {
8953              cam_format_t fmt;
8954              mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW, fmt);
8955              if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
8956                  rc = addChannel(QCAMERA_CH_TYPE_CALLBACK);
8957                  if (rc != NO_ERROR) {
8958                      delChannel(QCAMERA_CH_TYPE_PREVIEW);
8959                      if (!isRdiMode()) {
8960                          delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
8961                          delChannel(QCAMERA_CH_TYPE_VIDEO);
8962                      }
8963                      LOGE("failed!! rc = %d", rc);
8964                      return rc;
8965                  }
8966              }
8967          }
8968  
8969          if (NO_ERROR != rc) {
8970              delChannel(QCAMERA_CH_TYPE_PREVIEW);
8971              LOGE("failed!! rc = %d", rc);
8972          }
8973      }
8974  
8975      if ((rc != NO_ERROR) && (isDualCamera())) {
8976          mParameters.setDeferCamera(CAM_DEFER_FLUSH);
8977      }
8978  
8979      LOGI("X rc = %d", rc);
8980      return rc;
8981  }
8982  
8983  /*===========================================================================
8984   * FUNCTION   : unpreparePreview
8985   *
8986   * DESCRIPTION: delete channels for preview
8987   *
8988   * PARAMETERS : none
8989   *
8990   * RETURN     : none
8991   *==========================================================================*/
unpreparePreview()8992  void QCamera2HardwareInterface::unpreparePreview()
8993  {
8994      if (isDualCamera()) {
8995          mParameters.setDeferCamera(CAM_DEFER_FLUSH);
8996      }
8997      delChannel(QCAMERA_CH_TYPE_ZSL);
8998      delChannel(QCAMERA_CH_TYPE_PREVIEW);
8999      delChannel(QCAMERA_CH_TYPE_VIDEO);
9000      delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
9001      delChannel(QCAMERA_CH_TYPE_CALLBACK);
9002      delChannel(QCAMERA_CH_TYPE_RAW);
9003  }
9004  
9005  /*===========================================================================
9006   * FUNCTION   : playShutter
9007   *
9008   * DESCRIPTION: send request to play shutter sound
9009   *
9010   * PARAMETERS : none
9011   *
9012   * RETURN     : none
9013   *==========================================================================*/
playShutter()9014  void QCamera2HardwareInterface::playShutter(){
9015       if (mNotifyCb == NULL ||
9016           msgTypeEnabledWithLock(CAMERA_MSG_SHUTTER) == 0){
9017           LOGD("shutter msg not enabled or NULL cb");
9018           return;
9019       }
9020       LOGH("CAMERA_MSG_SHUTTER ");
9021       qcamera_callback_argm_t cbArg;
9022       memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
9023       cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK;
9024       cbArg.msg_type = CAMERA_MSG_SHUTTER;
9025       cbArg.ext1 = 0;
9026       cbArg.ext2 = false;
9027       m_cbNotifier.notifyCallback(cbArg);
9028  }
9029  
9030  /*===========================================================================
9031   * FUNCTION   : getChannelByHandle
9032   *
9033   * DESCRIPTION: return a channel by its handle
9034   *
9035   * PARAMETERS :
9036   *   @channelHandle : channel handle
9037   *
9038   * RETURN     : a channel obj if found, NULL if not found
9039   *==========================================================================*/
getChannelByHandle(uint32_t channelHandle)9040  QCameraChannel *QCamera2HardwareInterface::getChannelByHandle(uint32_t channelHandle)
9041  {
9042      for(int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
9043          if (m_channels[i] != NULL &&
9044              (validate_handle(m_channels[i]->getMyHandle(), channelHandle))) {
9045              return m_channels[i];
9046          }
9047      }
9048  
9049      return NULL;
9050  }
9051  /*===========================================================================
9052   * FUNCTION   : needPreviewFDCallback
9053   *
9054   * DESCRIPTION: decides if needPreviewFDCallback
9055   *
9056   * PARAMETERS :
9057   *   @num_faces : number of faces
9058   *
9059   * RETURN     : bool type of status
9060   *              true  -- success
9061   *              fale -- failure code
9062   *==========================================================================*/
needPreviewFDCallback(uint8_t num_faces)9063  bool QCamera2HardwareInterface::needPreviewFDCallback(uint8_t num_faces)
9064  {
9065      if (num_faces == 0 && mNumPreviewFaces == 0) {
9066          return false;
9067      }
9068  
9069      return true;
9070  }
9071  
9072  /*===========================================================================
9073   * FUNCTION   : processFaceDetectionReuslt
9074   *
9075   * DESCRIPTION: process face detection reuslt
9076   *
9077   * PARAMETERS :
9078   *   @faces_data : ptr to face processing result struct
9079   *
9080   * RETURN     : int32_t type of status
9081   *              NO_ERROR  -- success
9082   *              none-zero failure code
9083   *==========================================================================*/
processFaceDetectionResult(cam_faces_data_t * faces_data)9084  int32_t QCamera2HardwareInterface::processFaceDetectionResult(cam_faces_data_t *faces_data)
9085  {
9086      if (!mParameters.isFaceDetectionEnabled()) {
9087          LOGH("FaceDetection not enabled, no ops here");
9088          return NO_ERROR;
9089      }
9090  
9091      qcamera_face_detect_type_t fd_type = faces_data->detection_data.fd_type;
9092      cam_face_detection_data_t *detect_data = &(faces_data->detection_data);
9093      if ((NULL == mDataCb) ||
9094          (fd_type == QCAMERA_FD_PREVIEW && !msgTypeEnabled(CAMERA_MSG_PREVIEW_METADATA)) ||
9095          (!needPreviewFDCallback(detect_data->num_faces_detected))
9096  #ifndef VANILLA_HAL
9097          || (fd_type == QCAMERA_FD_SNAPSHOT && !msgTypeEnabled(CAMERA_MSG_META_DATA))
9098  #endif
9099          ) {
9100          LOGH("metadata msgtype not enabled, no ops here");
9101          return NO_ERROR;
9102      }
9103  
9104      if ((fd_type == QCAMERA_FD_PREVIEW) && (detect_data->update_flag == FALSE)) {
9105          // Don't send callback to app if this is skipped by fd at backend
9106          return NO_ERROR;
9107      }
9108  
9109      cam_dimension_t display_dim;
9110      mParameters.getStreamDimension(CAM_STREAM_TYPE_PREVIEW, display_dim);
9111      if (display_dim.width <= 0 || display_dim.height <= 0) {
9112          LOGE("Invalid preview width or height (%d x %d)",
9113                 display_dim.width, display_dim.height);
9114          return UNKNOWN_ERROR;
9115      }
9116  
9117      // process face detection result
9118      // need separate face detection in preview or snapshot type
9119      size_t faceResultSize = 0;
9120      size_t data_len = 0;
9121      if(fd_type == QCAMERA_FD_PREVIEW){
9122          //fd for preview frames
9123          faceResultSize = sizeof(camera_frame_metadata_t);
9124          faceResultSize += sizeof(camera_face_t) * MAX_ROI;
9125      }else if(fd_type == QCAMERA_FD_SNAPSHOT){
9126  #ifndef VANILLA_HAL
9127          // fd for snapshot frames
9128          //check if face is detected in this frame
9129          if(detect_data->num_faces_detected > 0){
9130              data_len = sizeof(camera_frame_metadata_t) +
9131                      sizeof(camera_face_t) * detect_data->num_faces_detected;
9132          }else{
9133              //no face
9134              data_len = 0;
9135          }
9136  #endif
9137          faceResultSize = 1 *sizeof(int)    //meta data type
9138                         + 1 *sizeof(int)    // meta data len
9139                         + data_len;         //data
9140      }
9141  
9142      camera_memory_t *faceResultBuffer = mGetMemory(-1,
9143                                                     faceResultSize,
9144                                                     1,
9145                                                     mCallbackCookie);
9146      if ( NULL == faceResultBuffer ) {
9147          LOGE("Not enough memory for face result data");
9148          return NO_MEMORY;
9149      }
9150  
9151      unsigned char *pFaceResult = ( unsigned char * ) faceResultBuffer->data;
9152      memset(pFaceResult, 0, faceResultSize);
9153      unsigned char *faceData = NULL;
9154      if(fd_type == QCAMERA_FD_PREVIEW){
9155          faceData = pFaceResult;
9156          mNumPreviewFaces = detect_data->num_faces_detected;
9157      }else if(fd_type == QCAMERA_FD_SNAPSHOT){
9158  #ifndef VANILLA_HAL
9159          //need fill meta type and meta data len first
9160          int *data_header = (int* )pFaceResult;
9161          data_header[0] = CAMERA_META_DATA_FD;
9162          data_header[1] = (int)data_len;
9163  
9164          if(data_len <= 0){
9165              //if face is not valid or do not have face, return
9166              qcamera_callback_argm_t cbArg;
9167              memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
9168              cbArg.cb_type = QCAMERA_DATA_CALLBACK;
9169              cbArg.msg_type = CAMERA_MSG_META_DATA;
9170              cbArg.data = faceResultBuffer;
9171              cbArg.user_data = faceResultBuffer;
9172              cbArg.cookie = this;
9173              cbArg.release_cb = releaseCameraMemory;
9174              int32_t rc = m_cbNotifier.notifyCallback(cbArg);
9175              if (rc != NO_ERROR) {
9176                  LOGE("fail sending notification");
9177                  faceResultBuffer->release(faceResultBuffer);
9178              }
9179              return rc;
9180          }
9181  #endif
9182          faceData = pFaceResult + 2 *sizeof(int); //skip two int length
9183      }
9184  
9185      camera_frame_metadata_t *roiData = (camera_frame_metadata_t * ) faceData;
9186      camera_face_t *faces = (camera_face_t *) ( faceData + sizeof(camera_frame_metadata_t) );
9187  
9188      roiData->number_of_faces = detect_data->num_faces_detected;
9189      roiData->faces = faces;
9190      LOGL("FD_DEBUG : Frame[%d] : number_of_faces=%d, display_dim=%d %d",
9191              detect_data->frame_id, detect_data->num_faces_detected,
9192              display_dim.width, display_dim.height);
9193      if (roiData->number_of_faces > 0) {
9194          for (int i = 0; i < roiData->number_of_faces; i++) {
9195              faces[i].id = detect_data->faces[i].face_id;
9196              faces[i].score = detect_data->faces[i].score;
9197  
9198              // left
9199              faces[i].rect[0] = MAP_TO_DRIVER_COORDINATE(
9200                      detect_data->faces[i].face_boundary.left,
9201                      display_dim.width, 2000, -1000);
9202  
9203              // top
9204              faces[i].rect[1] = MAP_TO_DRIVER_COORDINATE(
9205                      detect_data->faces[i].face_boundary.top,
9206                      display_dim.height, 2000, -1000);
9207  
9208              // right
9209              faces[i].rect[2] = faces[i].rect[0] +
9210                      MAP_TO_DRIVER_COORDINATE(
9211                      detect_data->faces[i].face_boundary.width,
9212                      display_dim.width, 2000, 0);
9213  
9214               // bottom
9215              faces[i].rect[3] = faces[i].rect[1] +
9216                      MAP_TO_DRIVER_COORDINATE(
9217                      detect_data->faces[i].face_boundary.height,
9218                      display_dim.height, 2000, 0);
9219  
9220              LOGL("FD_DEBUG : Frame[%d] : Face[%d] : id=%d, score=%d, "
9221                      "CAM[left=%d, top=%d, w=%d, h=%d], "
9222                      "APP[left=%d, top=%d, right=%d, bottom=%d] ",
9223                      detect_data->frame_id, i, faces[i].id, faces[i].score,
9224                      detect_data->faces[i].face_boundary.left,
9225                      detect_data->faces[i].face_boundary.top,
9226                      detect_data->faces[i].face_boundary.width,
9227                      detect_data->faces[i].face_boundary.height,
9228                      faces[i].rect[0], faces[i].rect[1],
9229                      faces[i].rect[2], faces[i].rect[3]);
9230  
9231              if (faces_data->landmark_valid) {
9232                  // Center of left eye
9233                  if (faces_data->landmark_data.face_landmarks[i].is_left_eye_valid) {
9234                      faces[i].left_eye[0] = MAP_TO_DRIVER_COORDINATE(
9235                              faces_data->landmark_data.face_landmarks[i].left_eye_center.x,
9236                              display_dim.width, 2000, -1000);
9237                      faces[i].left_eye[1] = MAP_TO_DRIVER_COORDINATE(
9238                              faces_data->landmark_data.face_landmarks[i].left_eye_center.y,
9239                              display_dim.height, 2000, -1000);
9240                  } else {
9241                      faces[i].left_eye[0] = FACE_INVALID_POINT;
9242                      faces[i].left_eye[1] = FACE_INVALID_POINT;
9243                  }
9244  
9245                  // Center of right eye
9246                  if (faces_data->landmark_data.face_landmarks[i].is_right_eye_valid) {
9247                      faces[i].right_eye[0] = MAP_TO_DRIVER_COORDINATE(
9248                              faces_data->landmark_data.face_landmarks[i].right_eye_center.x,
9249                              display_dim.width, 2000, -1000);
9250                      faces[i].right_eye[1] = MAP_TO_DRIVER_COORDINATE(
9251                              faces_data->landmark_data.face_landmarks[i].right_eye_center.y,
9252                              display_dim.height, 2000, -1000);
9253                  } else {
9254                      faces[i].right_eye[0] = FACE_INVALID_POINT;
9255                      faces[i].right_eye[1] = FACE_INVALID_POINT;
9256                  }
9257  
9258                  // Center of mouth
9259                  if (faces_data->landmark_data.face_landmarks[i].is_mouth_valid) {
9260                      faces[i].mouth[0] = MAP_TO_DRIVER_COORDINATE(
9261                              faces_data->landmark_data.face_landmarks[i].mouth_center.x,
9262                              display_dim.width, 2000, -1000);
9263                      faces[i].mouth[1] = MAP_TO_DRIVER_COORDINATE(
9264                              faces_data->landmark_data.face_landmarks[i].mouth_center.y,
9265                              display_dim.height, 2000, -1000);
9266                  } else {
9267                      faces[i].mouth[0] = FACE_INVALID_POINT;
9268                      faces[i].mouth[1] = FACE_INVALID_POINT;
9269                  }
9270  
9271                  LOGL("FD_DEBUG LANDMARK : Frame[%d] : Face[%d] : "
9272                          "eye : left(%d, %d) right(%d, %d), mouth(%d, %d)",
9273                          detect_data->frame_id, i, faces[i].left_eye[0], faces[i].left_eye[1],
9274                          faces[i].right_eye[0], faces[i].right_eye[1],
9275                          faces[i].mouth[0], faces[i].mouth[1]);
9276              } else {
9277                  // return -2000 if invalid
9278                  faces[i].left_eye[0] = FACE_INVALID_POINT;
9279                  faces[i].left_eye[1] = FACE_INVALID_POINT;
9280  
9281                  faces[i].right_eye[0] = FACE_INVALID_POINT;
9282                  faces[i].right_eye[1] = FACE_INVALID_POINT;
9283  
9284                  faces[i].mouth[0] = FACE_INVALID_POINT;
9285                  faces[i].mouth[1] = FACE_INVALID_POINT;
9286              }
9287  
9288  #ifndef VANILLA_HAL
9289  #ifdef TARGET_TS_MAKEUP
9290              mFaceRect.left = detect_data->faces[i].face_boundary.left;
9291              mFaceRect.top = detect_data->faces[i].face_boundary.top;
9292              mFaceRect.right = detect_data->faces[i].face_boundary.width+mFaceRect.left;
9293              mFaceRect.bottom = detect_data->faces[i].face_boundary.height+mFaceRect.top;
9294  #endif
9295              if (faces_data->smile_valid) {
9296                  faces[i].smile_degree = faces_data->smile_data.smile[i].smile_degree;
9297                  faces[i].smile_score = faces_data->smile_data.smile[i].smile_confidence;
9298  
9299                  LOGL("FD_DEBUG LANDMARK : Frame[%d] : Face[%d] : smile_degree=%d, smile_score=%d",
9300                          detect_data->frame_id, i, faces[i].smile_degree, faces[i].smile_score);
9301              }
9302              if (faces_data->blink_valid) {
9303                  faces[i].blink_detected = faces_data->blink_data.blink[i].blink_detected;
9304                  faces[i].leye_blink = faces_data->blink_data.blink[i].left_blink;
9305                  faces[i].reye_blink = faces_data->blink_data.blink[i].right_blink;
9306  
9307                  LOGL("FD_DEBUG LANDMARK : Frame[%d] : Face[%d] : "
9308                          "blink_detected=%d, leye_blink=%d, reye_blink=%d",
9309                          detect_data->frame_id, i, faces[i].blink_detected, faces[i].leye_blink,
9310                          faces[i].reye_blink);
9311              }
9312              if (faces_data->recog_valid) {
9313                  faces[i].face_recognised = faces_data->recog_data.face_rec[i].face_recognised;
9314  
9315                  LOGL("FD_DEBUG LANDMARK : Frame[%d] : Face[%d] : face_recognised=%d",
9316                          detect_data->frame_id, i, faces[i].face_recognised);
9317              }
9318              if (faces_data->gaze_valid) {
9319                  faces[i].gaze_angle = faces_data->gaze_data.gaze[i].gaze_angle;
9320                  faces[i].updown_dir = faces_data->gaze_data.gaze[i].updown_dir;
9321                  faces[i].leftright_dir = faces_data->gaze_data.gaze[i].leftright_dir;
9322                  faces[i].roll_dir = faces_data->gaze_data.gaze[i].roll_dir;
9323                  faces[i].left_right_gaze = faces_data->gaze_data.gaze[i].left_right_gaze;
9324                  faces[i].top_bottom_gaze = faces_data->gaze_data.gaze[i].top_bottom_gaze;
9325  
9326                  LOGL("FD_DEBUG LANDMARK : Frame[%d] : Face[%d] : gaze_angle=%d, updown_dir=%d, "
9327                          "leftright_dir=%d,, roll_dir=%d, left_right_gaze=%d, top_bottom_gaze=%d",
9328                          detect_data->frame_id, i, faces[i].gaze_angle, faces[i].updown_dir,
9329                          faces[i].leftright_dir, faces[i].roll_dir, faces[i].left_right_gaze,
9330                          faces[i].top_bottom_gaze);
9331              }
9332  #endif
9333  
9334          }
9335      }
9336      else{
9337  #ifdef TARGET_TS_MAKEUP
9338          memset(&mFaceRect,-1,sizeof(mFaceRect));
9339  #endif
9340      }
9341      qcamera_callback_argm_t cbArg;
9342      memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
9343      cbArg.cb_type = QCAMERA_DATA_CALLBACK;
9344      if(fd_type == QCAMERA_FD_PREVIEW){
9345          cbArg.msg_type = CAMERA_MSG_PREVIEW_METADATA;
9346      }
9347  #ifndef VANILLA_HAL
9348      else if(fd_type == QCAMERA_FD_SNAPSHOT){
9349          cbArg.msg_type = CAMERA_MSG_META_DATA;
9350      }
9351  #endif
9352      cbArg.data = faceResultBuffer;
9353      cbArg.metadata = roiData;
9354      cbArg.user_data = faceResultBuffer;
9355      cbArg.cookie = this;
9356      cbArg.release_cb = releaseCameraMemory;
9357      int32_t rc = m_cbNotifier.notifyCallback(cbArg);
9358      if (rc != NO_ERROR) {
9359          LOGE("fail sending notification");
9360          faceResultBuffer->release(faceResultBuffer);
9361      }
9362  
9363      return rc;
9364  }
9365  
9366  /*===========================================================================
9367   * FUNCTION   : releaseCameraMemory
9368   *
9369   * DESCRIPTION: releases camera memory objects
9370   *
9371   * PARAMETERS :
9372   *   @data    : buffer to be released
9373   *   @cookie  : context data
9374   *   @cbStatus: callback status
9375   *
9376   * RETURN     : None
9377   *==========================================================================*/
releaseCameraMemory(void * data,void *,int32_t)9378  void QCamera2HardwareInterface::releaseCameraMemory(void *data,
9379                                                      void */*cookie*/,
9380                                                      int32_t /*cbStatus*/)
9381  {
9382      camera_memory_t *mem = ( camera_memory_t * ) data;
9383      if ( NULL != mem ) {
9384          mem->release(mem);
9385      }
9386  }
9387  
9388  /*===========================================================================
9389   * FUNCTION   : returnStreamBuffer
9390   *
9391   * DESCRIPTION: returns back a stream buffer
9392   *
9393   * PARAMETERS :
9394   *   @data    : buffer to be released
9395   *   @cookie  : context data
9396   *   @cbStatus: callback status
9397   *
9398   * RETURN     : None
9399   *==========================================================================*/
returnStreamBuffer(void * data,void * cookie,int32_t)9400  void QCamera2HardwareInterface::returnStreamBuffer(void *data,
9401                                                     void *cookie,
9402                                                     int32_t /*cbStatus*/)
9403  {
9404      QCameraStream *stream = ( QCameraStream * ) cookie;
9405      int idx = *((int *)data);
9406      if ((NULL != stream) && (0 <= idx)) {
9407          stream->bufDone((uint32_t)idx);
9408      } else {
9409          LOGE("Cannot return buffer %d %p", idx, cookie);
9410      }
9411  }
9412  
9413  /*===========================================================================
9414   * FUNCTION   : processHistogramStats
9415   *
9416   * DESCRIPTION: process histogram stats
9417   *
9418   * PARAMETERS :
9419   *   @hist_data : ptr to histogram stats struct
9420   *
9421   * RETURN     : int32_t type of status
9422   *              NO_ERROR  -- success
9423   *              none-zero failure code
9424   *==========================================================================*/
processHistogramStats(__unused cam_hist_stats_t & stats_data)9425  int32_t QCamera2HardwareInterface::processHistogramStats(
9426          __unused cam_hist_stats_t &stats_data)
9427  {
9428  #ifndef VANILLA_HAL
9429      if (!mParameters.isHistogramEnabled()) {
9430          LOGH("Histogram not enabled, no ops here");
9431          return NO_ERROR;
9432      }
9433  
9434      camera_memory_t *histBuffer = mGetMemory(-1,
9435                                               sizeof(cam_histogram_data_t),
9436                                               1,
9437                                               mCallbackCookie);
9438      if ( NULL == histBuffer ) {
9439          LOGE("Not enough memory for histogram data");
9440          return NO_MEMORY;
9441      }
9442  
9443      cam_histogram_data_t *pHistData = (cam_histogram_data_t *)histBuffer->data;
9444      if (pHistData == NULL) {
9445          LOGE("memory data ptr is NULL");
9446          return UNKNOWN_ERROR;
9447      }
9448  
9449      switch (stats_data.type) {
9450      case CAM_HISTOGRAM_TYPE_BAYER:
9451          switch (stats_data.bayer_stats.data_type) {
9452              case CAM_STATS_CHANNEL_Y:
9453              case CAM_STATS_CHANNEL_R:
9454                  *pHistData = stats_data.bayer_stats.r_stats;
9455                  break;
9456              case CAM_STATS_CHANNEL_GR:
9457                  *pHistData = stats_data.bayer_stats.gr_stats;
9458                  break;
9459              case CAM_STATS_CHANNEL_GB:
9460              case CAM_STATS_CHANNEL_ALL:
9461                  *pHistData = stats_data.bayer_stats.gb_stats;
9462                  break;
9463              case CAM_STATS_CHANNEL_B:
9464                  *pHistData = stats_data.bayer_stats.b_stats;
9465                  break;
9466              default:
9467                  *pHistData = stats_data.bayer_stats.r_stats;
9468                  break;
9469          }
9470          break;
9471      case CAM_HISTOGRAM_TYPE_YUV:
9472          *pHistData = stats_data.yuv_stats;
9473          break;
9474      }
9475  
9476      qcamera_callback_argm_t cbArg;
9477      memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
9478      cbArg.cb_type = QCAMERA_DATA_CALLBACK;
9479      cbArg.msg_type = CAMERA_MSG_STATS_DATA;
9480      cbArg.data = histBuffer;
9481      cbArg.user_data = histBuffer;
9482      cbArg.cookie = this;
9483      cbArg.release_cb = releaseCameraMemory;
9484      int32_t rc = m_cbNotifier.notifyCallback(cbArg);
9485      if (rc != NO_ERROR) {
9486          LOGE("fail sending notification");
9487          histBuffer->release(histBuffer);
9488      }
9489  #endif
9490      return NO_ERROR;
9491  }
9492  
9493  /*===========================================================================
9494   * FUNCTION   : calcThermalLevel
9495   *
9496   * DESCRIPTION: Calculates the target fps range depending on
9497   *              the thermal level.
9498   *              Note that this function can be called from QCameraParametersIntf
9499   *              while mutex is held. So it should not call back into
9500   *              QCameraParametersIntf causing deadlock.
9501   *
9502   * PARAMETERS :
9503   *   @level      : received thermal level
9504   *   @minFPS     : minimum configured fps range
9505   *   @maxFPS     : maximum configured fps range
9506   *   @minVideoFps: minimum configured fps range
9507   *   @maxVideoFps: maximum configured fps range
9508   *   @adjustedRange : target fps range
9509   *   @skipPattern : target skip pattern
9510   *   @bRecordingHint : recording hint value
9511   *
9512   * RETURN     : int32_t type of status
9513   *              NO_ERROR  -- success
9514   *              none-zero failure code
9515   *==========================================================================*/
calcThermalLevel(qcamera_thermal_level_enum_t level,const int minFPSi,const int maxFPSi,const float & minVideoFps,const float & maxVideoFps,cam_fps_range_t & adjustedRange,enum msm_vfe_frame_skip_pattern & skipPattern,bool bRecordingHint)9516  int QCamera2HardwareInterface::calcThermalLevel(
9517              qcamera_thermal_level_enum_t level,
9518              const int minFPSi,
9519              const int maxFPSi,
9520              const float &minVideoFps,
9521              const float &maxVideoFps,
9522              cam_fps_range_t &adjustedRange,
9523              enum msm_vfe_frame_skip_pattern &skipPattern,
9524              bool bRecordingHint)
9525  {
9526      const float minFPS = (float)minFPSi;
9527      const float maxFPS = (float)maxFPSi;
9528  
9529      LOGH("level: %d, preview minfps %f, preview maxfpS %f, "
9530                "video minfps %f, video maxfpS %f",
9531               level, minFPS, maxFPS, minVideoFps, maxVideoFps);
9532  
9533      switch(level) {
9534      case QCAMERA_THERMAL_NO_ADJUSTMENT:
9535          {
9536              adjustedRange.min_fps = minFPS / 1000.0f;
9537              adjustedRange.max_fps = maxFPS / 1000.0f;
9538              adjustedRange.video_min_fps = minVideoFps / 1000.0f;
9539              adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
9540              skipPattern = NO_SKIP;
9541          }
9542          break;
9543      case QCAMERA_THERMAL_SLIGHT_ADJUSTMENT:
9544          {
9545              adjustedRange.min_fps = minFPS / 1000.0f;
9546              adjustedRange.max_fps = maxFPS / 1000.0f;
9547              adjustedRange.min_fps -= 0.1f * adjustedRange.min_fps;
9548              adjustedRange.max_fps -= 0.1f * adjustedRange.max_fps;
9549              adjustedRange.video_min_fps = minVideoFps / 1000.0f;
9550              adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
9551              adjustedRange.video_min_fps -= 0.1f * adjustedRange.video_min_fps;
9552              adjustedRange.video_max_fps -= 0.1f * adjustedRange.video_max_fps;
9553              if ( adjustedRange.min_fps < 1 ) {
9554                  adjustedRange.min_fps = 1;
9555              }
9556              if ( adjustedRange.max_fps < 1 ) {
9557                  adjustedRange.max_fps = 1;
9558              }
9559              if ( adjustedRange.video_min_fps < 1 ) {
9560                  adjustedRange.video_min_fps = 1;
9561              }
9562              if ( adjustedRange.video_max_fps < 1 ) {
9563                  adjustedRange.video_max_fps = 1;
9564              }
9565              skipPattern = EVERY_2FRAME;
9566          }
9567          break;
9568      case QCAMERA_THERMAL_BIG_ADJUSTMENT:
9569          {
9570              adjustedRange.min_fps = minFPS / 1000.0f;
9571              adjustedRange.max_fps = maxFPS / 1000.0f;
9572              adjustedRange.min_fps -= 0.2f * adjustedRange.min_fps;
9573              adjustedRange.max_fps -= 0.2f * adjustedRange.max_fps;
9574              adjustedRange.video_min_fps = minVideoFps / 1000.0f;
9575              adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
9576              adjustedRange.video_min_fps -= 0.2f * adjustedRange.video_min_fps;
9577              adjustedRange.video_max_fps -= 0.2f * adjustedRange.video_max_fps;
9578              if ( adjustedRange.min_fps < 1 ) {
9579                  adjustedRange.min_fps = 1;
9580              }
9581              if ( adjustedRange.max_fps < 1 ) {
9582                  adjustedRange.max_fps = 1;
9583              }
9584              if ( adjustedRange.video_min_fps < 1 ) {
9585                  adjustedRange.video_min_fps = 1;
9586              }
9587              if ( adjustedRange.video_max_fps < 1 ) {
9588                  adjustedRange.video_max_fps = 1;
9589              }
9590              skipPattern = EVERY_4FRAME;
9591          }
9592          break;
9593      case QCAMERA_THERMAL_MAX_ADJUSTMENT:
9594          {
9595              // Stop Preview?
9596              // Set lowest min FPS for now
9597              adjustedRange.min_fps = minFPS/1000.0f;
9598              adjustedRange.max_fps = minFPS/1000.0f;
9599              cam_capability_t *capability = gCamCapability[mCameraId];
9600              for (size_t i = 0;
9601                       i < capability->fps_ranges_tbl_cnt;
9602                       i++) {
9603                  if (capability->fps_ranges_tbl[i].min_fps <
9604                          adjustedRange.min_fps) {
9605                      adjustedRange.min_fps =
9606                              capability->fps_ranges_tbl[i].min_fps;
9607                      adjustedRange.max_fps = adjustedRange.min_fps;
9608                  }
9609              }
9610              skipPattern = MAX_SKIP;
9611              adjustedRange.video_min_fps = adjustedRange.min_fps;
9612              adjustedRange.video_max_fps = adjustedRange.max_fps;
9613          }
9614          break;
9615      case QCAMERA_THERMAL_SHUTDOWN:
9616          {
9617              // send error notify
9618              LOGE("Received shutdown thermal level. Closing camera");
9619              sendEvtNotify(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0);
9620          }
9621          break;
9622      default:
9623          {
9624              LOGW("Invalid thermal level %d", level);
9625              return BAD_VALUE;
9626          }
9627          break;
9628      }
9629      if (level >= QCAMERA_THERMAL_NO_ADJUSTMENT && level <= QCAMERA_THERMAL_MAX_ADJUSTMENT) {
9630          if (bRecordingHint) {
9631              adjustedRange.min_fps = minFPS / 1000.0f;
9632              adjustedRange.max_fps = maxFPS / 1000.0f;
9633              adjustedRange.video_min_fps = minVideoFps / 1000.0f;
9634              adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
9635              skipPattern = NO_SKIP;
9636              LOGH("No FPS mitigation in camcorder mode");
9637          }
9638          LOGH("Thermal level %d, FPS [%3.2f,%3.2f, %3.2f,%3.2f], frameskip %d",
9639                    level, adjustedRange.min_fps, adjustedRange.max_fps,
9640                      adjustedRange.video_min_fps, adjustedRange.video_max_fps, skipPattern);
9641      }
9642  
9643      return NO_ERROR;
9644  }
9645  
9646  /*===========================================================================
9647   * FUNCTION   : recalcFPSRange
9648   *
9649   * DESCRIPTION: adjust the configured fps range regarding
9650   *              the last thermal level.
9651   *
9652   * PARAMETERS :
9653   *   @minFPS      : minimum configured fps range
9654   *   @maxFPS      : maximum configured fps range
9655   *   @minVideoFPS : minimum configured video fps
9656   *   @maxVideoFPS : maximum configured video fps
9657   *   @adjustedRange : target fps range
9658   *   @bRecordingHint : recording hint value
9659   *
9660   * RETURN     : int32_t type of status
9661   *              NO_ERROR  -- success
9662   *              none-zero failure code
9663   *==========================================================================*/
recalcFPSRange(int & minFPS,int & maxFPS,const float & minVideoFPS,const float & maxVideoFPS,cam_fps_range_t & adjustedRange,bool bRecordingHint)9664  int QCamera2HardwareInterface::recalcFPSRange(int &minFPS, int &maxFPS,
9665          const float &minVideoFPS, const float &maxVideoFPS,
9666          cam_fps_range_t &adjustedRange, bool bRecordingHint)
9667  {
9668      enum msm_vfe_frame_skip_pattern skipPattern;
9669      calcThermalLevel(mThermalLevel,
9670                       minFPS,
9671                       maxFPS,
9672                       minVideoFPS,
9673                       maxVideoFPS,
9674                       adjustedRange,
9675                       skipPattern,
9676                       bRecordingHint);
9677      return NO_ERROR;
9678  }
9679  
9680  /*===========================================================================
9681   * FUNCTION   : updateThermalLevel
9682   *
9683   * DESCRIPTION: update thermal level depending on thermal events
9684   *
9685   * PARAMETERS :
9686   *   @level   : thermal level
9687   *
9688   * RETURN     : int32_t type of status
9689   *              NO_ERROR  -- success
9690   *              none-zero failure code
9691   *==========================================================================*/
updateThermalLevel(void * thermal_level)9692  int QCamera2HardwareInterface::updateThermalLevel(void *thermal_level)
9693  {
9694      int ret = NO_ERROR;
9695      cam_fps_range_t adjustedRange;
9696      int minFPS, maxFPS;
9697      float minVideoFPS, maxVideoFPS;
9698      enum msm_vfe_frame_skip_pattern skipPattern;
9699      bool value;
9700      qcamera_thermal_level_enum_t level = *(qcamera_thermal_level_enum_t *)thermal_level;
9701  
9702  
9703      if (!mCameraOpened) {
9704          LOGH("Camera is not opened, no need to update camera parameters");
9705          return NO_ERROR;
9706      }
9707  
9708      mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
9709      qcamera_thermal_mode thermalMode = mParameters.getThermalMode();
9710      if (mParameters.isHfrMode()) {
9711          cam_fps_range_t hfrFpsRange;
9712          mParameters.getHfrFps(hfrFpsRange);
9713          minVideoFPS = hfrFpsRange.video_min_fps;
9714          maxVideoFPS = hfrFpsRange.video_max_fps;
9715      } else {
9716          minVideoFPS = minFPS;
9717          maxVideoFPS = maxFPS;
9718      }
9719  
9720      value = mParameters.getRecordingHintValue();
9721      calcThermalLevel(level, minFPS, maxFPS, minVideoFPS, maxVideoFPS,
9722              adjustedRange, skipPattern, value );
9723      mThermalLevel = level;
9724  
9725      if (thermalMode == QCAMERA_THERMAL_ADJUST_FPS)
9726          ret = mParameters.adjustPreviewFpsRange(&adjustedRange);
9727      else if (thermalMode == QCAMERA_THERMAL_ADJUST_FRAMESKIP)
9728          ret = mParameters.setFrameSkip(skipPattern);
9729      else
9730          LOGW("Incorrect thermal mode %d", thermalMode);
9731  
9732      return ret;
9733  
9734  }
9735  
9736  /*===========================================================================
9737   * FUNCTION   : updateParameters
9738   *
9739   * DESCRIPTION: update parameters
9740   *
9741   * PARAMETERS :
9742   *   @parms       : input parameters string
9743   *   @needRestart : output, flag to indicate if preview restart is needed
9744   *
9745   * RETURN     : int32_t type of status
9746   *              NO_ERROR  -- success
9747   *              none-zero failure code
9748   *==========================================================================*/
updateParameters(const char * parms,bool & needRestart)9749  int QCamera2HardwareInterface::updateParameters(const char *parms, bool &needRestart)
9750  {
9751      int rc = NO_ERROR;
9752  
9753      String8 str = String8(parms);
9754      rc =  mParameters.updateParameters(str, needRestart);
9755      setNeedRestart(needRestart);
9756  
9757      // update stream based parameter settings
9758      for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
9759          if (m_channels[i] != NULL) {
9760              m_channels[i]->UpdateStreamBasedParameters(mParameters);
9761          }
9762      }
9763  
9764      return rc;
9765  }
9766  
9767  /*===========================================================================
9768   * FUNCTION   : commitParameterChanges
9769   *
9770   * DESCRIPTION: commit parameter changes to the backend to take effect
9771   *
9772   * PARAMETERS : none
9773   *
9774   * RETURN     : int32_t type of status
9775   *              NO_ERROR  -- success
9776   *              none-zero failure code
9777   * NOTE       : This function must be called after updateParameters.
9778   *              Otherwise, no change will be passed to backend to take effect.
9779   *==========================================================================*/
commitParameterChanges()9780  int QCamera2HardwareInterface::commitParameterChanges()
9781  {
9782      int rc = NO_ERROR;
9783      rc = mParameters.commitParameters();
9784      if (rc == NO_ERROR) {
9785          // update number of snapshot based on committed parameters setting
9786          rc = mParameters.setNumOfSnapshot();
9787      }
9788  
9789      if (isDualCamera() &&
9790          mParameters.isZoomChanged()) {
9791          // If zoom changes, get the updated FOV-control result and if needed send the dual
9792          // camera parameters to backend
9793          processDualCamFovControl();
9794      }
9795      return rc;
9796  }
9797  
9798  /*===========================================================================
9799   * FUNCTION   : needDebugFps
9800   *
9801   * DESCRIPTION: if fps log info need to be printed out
9802   *
9803   * PARAMETERS : none
9804   *
9805   * RETURN     : true: need print out fps log
9806   *              false: no need to print out fps log
9807   *==========================================================================*/
needDebugFps()9808  bool QCamera2HardwareInterface::needDebugFps()
9809  {
9810      bool needFps = false;
9811      needFps = mParameters.isFpsDebugEnabled();
9812      return needFps;
9813  }
9814  
9815  /*===========================================================================
9816   * FUNCTION   : isCACEnabled
9817   *
9818   * DESCRIPTION: if CAC is enabled
9819   *
9820   * PARAMETERS : none
9821   *
9822   * RETURN     : true: needed
9823   *              false: no need
9824   *==========================================================================*/
isCACEnabled()9825  bool QCamera2HardwareInterface::isCACEnabled()
9826  {
9827      char prop[PROPERTY_VALUE_MAX];
9828      memset(prop, 0, sizeof(prop));
9829      property_get("persist.camera.feature.cac", prop, "0");
9830      int enableCAC = atoi(prop);
9831      return enableCAC == 1;
9832  }
9833  
9834  /*===========================================================================
9835   * FUNCTION   : is4k2kResolution
9836   *
9837   * DESCRIPTION: if resolution is 4k x 2k or true 4k x 2k
9838   *
9839   * PARAMETERS : none
9840   *
9841   * RETURN     : true: needed
9842   *              false: no need
9843   *==========================================================================*/
is4k2kResolution(cam_dimension_t * resolution)9844  bool QCamera2HardwareInterface::is4k2kResolution(cam_dimension_t* resolution)
9845  {
9846     bool enabled = false;
9847     if ((resolution->width == 4096 && resolution->height == 2160) ||
9848         (resolution->width == 3840 && resolution->height == 2160) ) {
9849        enabled = true;
9850     }
9851     return enabled;
9852  }
9853  
9854  /*===========================================================================
9855   * FUNCTION   : isPreviewRestartEnabled
9856   *
9857   * DESCRIPTION: Check whether preview should be restarted automatically
9858   *              during image capture.
9859   *
9860   * PARAMETERS : none
9861   *
9862   * RETURN     : true: needed
9863   *              false: no need
9864   *==========================================================================*/
isPreviewRestartEnabled()9865  bool QCamera2HardwareInterface::isPreviewRestartEnabled()
9866  {
9867      char prop[PROPERTY_VALUE_MAX];
9868      memset(prop, 0, sizeof(prop));
9869      property_get("persist.camera.feature.restart", prop, "0");
9870      int earlyRestart = atoi(prop);
9871      return earlyRestart == 1;
9872  }
9873  
9874  /*===========================================================================
9875   * FUNCTION   : needReprocess
9876   *
9877   * DESCRIPTION: if reprocess is needed
9878   *
9879   * PARAMETERS : none
9880   *
9881   * RETURN     : true: needed
9882   *              false: no need
9883   *==========================================================================*/
needReprocess()9884  bool QCamera2HardwareInterface::needReprocess()
9885  {
9886      bool needReprocess = false;
9887  
9888      if (!mParameters.isJpegPictureFormat() &&
9889          !mParameters.isNV21PictureFormat()) {
9890          // RAW image, no need to reprocess
9891          return false;
9892      }
9893  
9894      //Disable reprocess for small jpeg size or 4K liveshot case but enable if lowpower mode
9895      if ((mParameters.is4k2kVideoResolution() && mParameters.getRecordingHintValue()
9896              && !isLowPowerMode()) || mParameters.isSmallJpegSizeEnabled()) {
9897          return false;
9898      }
9899  
9900      // pp feature config
9901      cam_pp_feature_config_t pp_config;
9902      memset(&pp_config, 0, sizeof(cam_pp_feature_config_t));
9903  
9904      //Decide whether to do reprocess or not based on
9905      //ppconfig obtained in the first pass.
9906      getPPConfig(pp_config);
9907  
9908      if (pp_config.feature_mask > 0) {
9909          needReprocess = true;
9910      }
9911  
9912      LOGH("needReprocess %s", needReprocess ? "true" : "false");
9913      return needReprocess;
9914  }
9915  
9916  
9917  /*===========================================================================
9918   * FUNCTION   : needRotationReprocess
9919   *
9920   * DESCRIPTION: if rotation needs to be done by reprocess in pp
9921   *
9922   * PARAMETERS : none
9923   *
9924   * RETURN     : true: needed
9925   *              false: no need
9926   *==========================================================================*/
needRotationReprocess()9927  bool QCamera2HardwareInterface::needRotationReprocess()
9928  {
9929      if (!mParameters.isJpegPictureFormat() &&
9930          !mParameters.isNV21PictureFormat()) {
9931          // RAW image, no need to reprocess
9932          return false;
9933      }
9934  
9935      //Disable reprocess for 4K liveshot case
9936      if ((mParameters.is4k2kVideoResolution() && mParameters.getRecordingHintValue()
9937              && !isLowPowerMode()) || mParameters.isSmallJpegSizeEnabled()) {
9938          //Disable reprocess for 4K liveshot case or small jpeg size
9939           return false;
9940      }
9941  
9942      if ((gCamCapability[mCameraId]->qcom_supported_feature_mask &
9943              CAM_QCOM_FEATURE_ROTATION) > 0 &&
9944              (mParameters.getJpegRotation() > 0)) {
9945          // current rotation is not zero, and pp has the capability to process rotation
9946          LOGH("need to do reprocess for rotation=%d",
9947                   mParameters.getJpegRotation());
9948          return true;
9949      }
9950  
9951      return false;
9952  }
9953  
9954  /*===========================================================================
9955   * FUNCTION   : getThumbnailSize
9956   *
9957   * DESCRIPTION: get user set thumbnail size
9958   *
9959   * PARAMETERS :
9960   *   @dim     : output of thumbnail dimension
9961   *
9962   * RETURN     : none
9963   *==========================================================================*/
getThumbnailSize(cam_dimension_t & dim)9964  void QCamera2HardwareInterface::getThumbnailSize(cam_dimension_t &dim)
9965  {
9966      mParameters.getThumbnailSize(&dim.width, &dim.height);
9967  }
9968  
9969  /*===========================================================================
9970   * FUNCTION   : getJpegQuality
9971   *
9972   * DESCRIPTION: get user set jpeg quality
9973   *
9974   * PARAMETERS : none
9975   *
9976   * RETURN     : jpeg quality setting
9977   *==========================================================================*/
getJpegQuality()9978  uint32_t QCamera2HardwareInterface::getJpegQuality()
9979  {
9980      uint32_t quality = 0;
9981      quality =  mParameters.getJpegQuality();
9982      return quality;
9983  }
9984  
9985  /*===========================================================================
9986   * FUNCTION   : getExifData
9987   *
9988   * DESCRIPTION: get exif data to be passed into jpeg encoding
9989   *
9990   * PARAMETERS : none
9991   *
9992   * RETURN     : exif data from user setting and GPS
9993   *==========================================================================*/
getExifData()9994  QCameraExif *QCamera2HardwareInterface::getExifData()
9995  {
9996      QCameraExif *exif = new QCameraExif();
9997      if (exif == NULL) {
9998          LOGE("No memory for QCameraExif");
9999          return NULL;
10000      }
10001  
10002      int32_t rc = NO_ERROR;
10003  
10004      // add exif entries
10005      String8 dateTime, subSecTime;
10006      rc = mParameters.getExifDateTime(dateTime, subSecTime);
10007      if(rc == NO_ERROR) {
10008          exif->addEntry(EXIFTAGID_DATE_TIME, EXIF_ASCII,
10009                  (uint32_t)(dateTime.length() + 1), (void *)dateTime.string());
10010          exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, EXIF_ASCII,
10011                  (uint32_t)(dateTime.length() + 1), (void *)dateTime.string());
10012          exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_DIGITIZED, EXIF_ASCII,
10013                  (uint32_t)(dateTime.length() + 1), (void *)dateTime.string());
10014          exif->addEntry(EXIFTAGID_SUBSEC_TIME, EXIF_ASCII,
10015                  (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string());
10016          exif->addEntry(EXIFTAGID_SUBSEC_TIME_ORIGINAL, EXIF_ASCII,
10017                  (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string());
10018          exif->addEntry(EXIFTAGID_SUBSEC_TIME_DIGITIZED, EXIF_ASCII,
10019                  (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string());
10020      } else {
10021          LOGW("getExifDateTime failed");
10022      }
10023  
10024      rat_t focalLength;
10025      rc = mParameters.getExifFocalLength(&focalLength);
10026      if (rc == NO_ERROR) {
10027          exif->addEntry(EXIFTAGID_FOCAL_LENGTH,
10028                         EXIF_RATIONAL,
10029                         1,
10030                         (void *)&(focalLength));
10031      } else {
10032          LOGW("getExifFocalLength failed");
10033      }
10034  
10035      uint16_t isoSpeed = mParameters.getExifIsoSpeed();
10036      if (getSensorType() != CAM_SENSOR_YUV) {
10037          exif->addEntry(EXIFTAGID_ISO_SPEED_RATING,
10038                         EXIF_SHORT,
10039                         1,
10040                         (void *)&(isoSpeed));
10041      }
10042  
10043      char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE];
10044      uint32_t count = 0;
10045  
10046      /*gps data might not be available */
10047      rc = mParameters.getExifGpsProcessingMethod(gpsProcessingMethod, count);
10048      if(rc == NO_ERROR) {
10049          exif->addEntry(EXIFTAGID_GPS_PROCESSINGMETHOD,
10050                         EXIF_ASCII,
10051                         count,
10052                         (void *)gpsProcessingMethod);
10053      } else {
10054          LOGW("getExifGpsProcessingMethod failed");
10055      }
10056  
10057      rat_t latitude[3];
10058      char latRef[2];
10059      rc = mParameters.getExifLatitude(latitude, latRef);
10060      if(rc == NO_ERROR) {
10061          exif->addEntry(EXIFTAGID_GPS_LATITUDE,
10062                         EXIF_RATIONAL,
10063                         3,
10064                         (void *)latitude);
10065          exif->addEntry(EXIFTAGID_GPS_LATITUDE_REF,
10066                         EXIF_ASCII,
10067                         2,
10068                         (void *)latRef);
10069      } else {
10070          LOGW("getExifLatitude failed");
10071      }
10072  
10073      rat_t longitude[3];
10074      char lonRef[2];
10075      rc = mParameters.getExifLongitude(longitude, lonRef);
10076      if(rc == NO_ERROR) {
10077          exif->addEntry(EXIFTAGID_GPS_LONGITUDE,
10078                         EXIF_RATIONAL,
10079                         3,
10080                         (void *)longitude);
10081  
10082          exif->addEntry(EXIFTAGID_GPS_LONGITUDE_REF,
10083                         EXIF_ASCII,
10084                         2,
10085                         (void *)lonRef);
10086      } else {
10087          LOGW("getExifLongitude failed");
10088      }
10089  
10090      rat_t altitude;
10091      char altRef;
10092      rc = mParameters.getExifAltitude(&altitude, &altRef);
10093      if(rc == NO_ERROR) {
10094          exif->addEntry(EXIFTAGID_GPS_ALTITUDE,
10095                         EXIF_RATIONAL,
10096                         1,
10097                         (void *)&(altitude));
10098  
10099          exif->addEntry(EXIFTAGID_GPS_ALTITUDE_REF,
10100                         EXIF_BYTE,
10101                         1,
10102                         (void *)&altRef);
10103      } else {
10104          LOGW("getExifAltitude failed");
10105      }
10106  
10107      char gpsDateStamp[20];
10108      rat_t gpsTimeStamp[3];
10109      rc = mParameters.getExifGpsDateTimeStamp(gpsDateStamp, 20, gpsTimeStamp);
10110      if(rc == NO_ERROR) {
10111          exif->addEntry(EXIFTAGID_GPS_DATESTAMP,
10112                         EXIF_ASCII,
10113                         (uint32_t)(strlen(gpsDateStamp) + 1),
10114                         (void *)gpsDateStamp);
10115  
10116          exif->addEntry(EXIFTAGID_GPS_TIMESTAMP,
10117                         EXIF_RATIONAL,
10118                         3,
10119                         (void *)gpsTimeStamp);
10120      } else {
10121          LOGW("getExifGpsDataTimeStamp failed");
10122      }
10123  
10124  #ifdef ENABLE_MODEL_INFO_EXIF
10125  
10126      char value[PROPERTY_VALUE_MAX];
10127      if (property_get("persist.sys.exif.make", value, "") > 0 ||
10128              property_get("ro.product.manufacturer", value, "QCOM-AA") > 0) {
10129          exif->addEntry(EXIFTAGID_MAKE,
10130                  EXIF_ASCII, strlen(value) + 1, (void *)value);
10131      } else {
10132          LOGW("getExifMaker failed");
10133      }
10134  
10135      if (property_get("persist.sys.exif.model", value, "") > 0 ||
10136              property_get("ro.product.model", value, "QCAM-AA") > 0) {
10137          exif->addEntry(EXIFTAGID_MODEL,
10138                  EXIF_ASCII, strlen(value) + 1, (void *)value);
10139      } else {
10140          LOGW("getExifModel failed");
10141      }
10142  
10143      if (property_get("ro.build.description", value, "QCAM-AA") > 0) {
10144          exif->addEntry(EXIFTAGID_SOFTWARE, EXIF_ASCII,
10145                  (uint32_t)(strlen(value) + 1), (void *)value);
10146      } else {
10147          LOGW("getExifSoftware failed");
10148      }
10149  
10150  #endif
10151  
10152      if (mParameters.useJpegExifRotation()) {
10153          int16_t orientation;
10154          switch (mParameters.getJpegExifRotation()) {
10155          case 0:
10156              orientation = 1;
10157              break;
10158          case 90:
10159              orientation = 6;
10160              break;
10161          case 180:
10162              orientation = 3;
10163              break;
10164          case 270:
10165              orientation = 8;
10166              break;
10167          default:
10168              orientation = 1;
10169              break;
10170          }
10171          exif->addEntry(EXIFTAGID_ORIENTATION,
10172                  EXIF_SHORT,
10173                  1,
10174                  (void *)&orientation);
10175          exif->addEntry(EXIFTAGID_TN_ORIENTATION,
10176                  EXIF_SHORT,
10177                  1,
10178                  (void *)&orientation);
10179      }
10180  
10181      return exif;
10182  }
10183  
10184  /*===========================================================================
10185   * FUNCTION   : setHistogram
10186   *
10187   * DESCRIPTION: set if histogram should be enabled
10188   *
10189   * PARAMETERS :
10190   *   @histogram_en : bool flag if histogram should be enabled
10191   *
10192   * RETURN     : int32_t type of status
10193   *              NO_ERROR  -- success
10194   *              none-zero failure code
10195   *==========================================================================*/
setHistogram(bool histogram_en)10196  int32_t QCamera2HardwareInterface::setHistogram(bool histogram_en)
10197  {
10198      return mParameters.setHistogram(histogram_en);
10199  }
10200  
10201  /*===========================================================================
10202   * FUNCTION   : setFaceDetection
10203   *
10204   * DESCRIPTION: set if face detection should be enabled
10205   *
10206   * PARAMETERS :
10207   *   @enabled : bool flag if face detection should be enabled
10208   *
10209   * RETURN     : int32_t type of status
10210   *              NO_ERROR  -- success
10211   *              none-zero failure code
10212   *==========================================================================*/
setFaceDetection(bool enabled)10213  int32_t QCamera2HardwareInterface::setFaceDetection(bool enabled)
10214  {
10215      return mParameters.setFaceDetection(enabled, true);
10216  }
10217  
10218  /*===========================================================================
10219   * FUNCTION   : isCaptureShutterEnabled
10220   *
10221   * DESCRIPTION: Check whether shutter should be triggered immediately after
10222   *              capture
10223   *
10224   * PARAMETERS :
10225   *
10226   * RETURN     : true - regular capture
10227   *              false - other type of capture
10228   *==========================================================================*/
isCaptureShutterEnabled()10229  bool QCamera2HardwareInterface::isCaptureShutterEnabled()
10230  {
10231      char prop[PROPERTY_VALUE_MAX];
10232      memset(prop, 0, sizeof(prop));
10233      property_get("persist.camera.feature.shutter", prop, "0");
10234      int enableShutter = atoi(prop);
10235      return enableShutter == 1;
10236  }
10237  
10238  /*===========================================================================
10239   * FUNCTION   : needProcessPreviewFrame
10240   *
10241   * DESCRIPTION: returns whether preview frame need to be displayed
10242   *
10243   * PARAMETERS :
10244   *   @frameID : frameID of frame to be processed
10245   *
10246   * RETURN     : int32_t type of status
10247   *              NO_ERROR  -- success
10248   *              none-zero failure code
10249   *==========================================================================*/
needProcessPreviewFrame(uint32_t frameID)10250  bool QCamera2HardwareInterface::needProcessPreviewFrame(uint32_t frameID)
10251  {
10252      return (((m_stateMachine.isPreviewRunning()) &&
10253              (!isDisplayFrameToSkip(frameID)) &&
10254              (!mParameters.isInstantAECEnabled())) ||
10255              (isPreviewRestartEnabled()));
10256  }
10257  
10258  /*===========================================================================
10259   * FUNCTION   : needSendPreviewCallback
10260   *
10261   * DESCRIPTION: returns whether preview frame need to callback to APP
10262   *
10263   * PARAMETERS :
10264   *
10265   * RETURN     : true - need preview frame callbck
10266   *              false - not send preview frame callback
10267   *==========================================================================*/
needSendPreviewCallback()10268  bool QCamera2HardwareInterface::needSendPreviewCallback()
10269  {
10270      return m_stateMachine.isPreviewRunning()
10271              && (mDataCb != NULL)
10272              && (msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_FRAME) > 0)
10273              && m_stateMachine.isPreviewCallbackNeeded();
10274  };
10275  
10276  /*===========================================================================
10277   * FUNCTION   : setDisplaySkip
10278   *
10279   * DESCRIPTION: set range of frames to skip for preview
10280   *
10281   * PARAMETERS :
10282   *   @enabled : TRUE to start skipping frame to display
10283                  FALSE to stop skipping frame to display
10284   *   @skipCnt : Number of frame to skip. 0 by default
10285   *
10286   * RETURN     : None
10287   *==========================================================================*/
setDisplaySkip(bool enabled,uint8_t skipCnt)10288  void QCamera2HardwareInterface::setDisplaySkip(bool enabled, uint8_t skipCnt)
10289  {
10290      pthread_mutex_lock(&mGrallocLock);
10291      if (enabled) {
10292          setDisplayFrameSkip();
10293          setDisplayFrameSkip(mLastPreviewFrameID + skipCnt + 1);
10294      } else {
10295          setDisplayFrameSkip(mFrameSkipStart, (mLastPreviewFrameID + skipCnt + 1));
10296      }
10297      pthread_mutex_unlock(&mGrallocLock);
10298  }
10299  
10300  /*===========================================================================
10301   * FUNCTION   : setDisplayFrameSkip
10302   *
10303   * DESCRIPTION: set range of frames to skip for preview
10304   *
10305   * PARAMETERS :
10306   *   @start   : frameId to start skip
10307   *   @end     : frameId to stop skip
10308   *
10309   * RETURN     : None
10310   *==========================================================================*/
setDisplayFrameSkip(uint32_t start,uint32_t end)10311  void QCamera2HardwareInterface::setDisplayFrameSkip(uint32_t start,
10312          uint32_t end)
10313  {
10314      if (start == 0) {
10315          mFrameSkipStart = 0;
10316          mFrameSkipEnd = 0;
10317          return;
10318      }
10319      if ((mFrameSkipStart == 0) || (mFrameSkipStart > start)) {
10320          mFrameSkipStart = start;
10321      }
10322      if ((end == 0) || (end > mFrameSkipEnd)) {
10323          mFrameSkipEnd = end;
10324      }
10325  }
10326  
10327  /*===========================================================================
10328   * FUNCTION   : isDisplayFrameToSkip
10329   *
10330   * DESCRIPTION: function to determin if input frame falls under skip range
10331   *
10332   * PARAMETERS :
10333   *   @frameId : frameId to verify
10334   *
10335   * RETURN     : true : need to skip
10336   *              false: no need to skip
10337   *==========================================================================*/
isDisplayFrameToSkip(uint32_t frameId)10338  bool QCamera2HardwareInterface::isDisplayFrameToSkip(uint32_t frameId)
10339  {
10340      return ((mFrameSkipStart != 0) && (frameId >= mFrameSkipStart) &&
10341              (frameId <= mFrameSkipEnd || mFrameSkipEnd == 0)) ? TRUE : FALSE;
10342  }
10343  
10344  /*===========================================================================
10345   * FUNCTION   : getSnapshotHandle
10346   *
10347   * DESCRIPTION: Get the camera handle for snapshot based on the bundlesnapshot
10348   *              flag and active camera state
10349   *
10350   * PARAMETERS : None
10351   *
10352   * RETURN     : camera handle for snapshot
10353   *
10354   *==========================================================================*/
getSnapshotHandle()10355  uint32_t QCamera2HardwareInterface::getSnapshotHandle()
10356  {
10357      uint32_t snapshotHandle = 0;
10358  
10359      if ((mActiveCameras == MM_CAMERA_DUAL_CAM) && mBundledSnapshot) {
10360          snapshotHandle = mCameraHandle->camera_handle;
10361      } else {
10362          snapshotHandle = (mMasterCamera == MM_CAMERA_TYPE_MAIN) ?
10363                  get_main_camera_handle(mCameraHandle->camera_handle) :
10364                  get_aux_camera_handle(mCameraHandle->camera_handle);
10365      }
10366  
10367      return snapshotHandle;
10368  }
10369  
10370  /*===========================================================================
10371   * FUNCTION   : prepareHardwareForSnapshot
10372   *
10373   * DESCRIPTION: prepare hardware for snapshot, such as LED
10374   *
10375   * PARAMETERS :
10376   *   @afNeeded: flag indicating if Auto Focus needs to be done during preparation
10377   *
10378   * RETURN     : int32_t type of status
10379   *              NO_ERROR  -- success
10380   *              none-zero failure code
10381   *==========================================================================*/
prepareHardwareForSnapshot(int32_t afNeeded)10382  int32_t QCamera2HardwareInterface::prepareHardwareForSnapshot(int32_t afNeeded)
10383  {
10384      ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PREPARE_HW_FOR_SNAPSHOT);
10385      LOGI("[KPI Perf]: Send PREPARE SANSPHOT event");
10386      return mCameraHandle->ops->prepare_snapshot(getSnapshotHandle(),
10387                                                  afNeeded);
10388  }
10389  
10390  /*===========================================================================
10391   * FUNCTION   : needFDMetadata
10392   *
10393   * DESCRIPTION: check whether we need process Face Detection metadata in this chanel
10394   *
10395   * PARAMETERS :
10396   *   @channel_type: channel type
10397   *
10398    * RETURN     : true: needed
10399   *              false: no need
10400   *==========================================================================*/
needFDMetadata(qcamera_ch_type_enum_t channel_type)10401  bool QCamera2HardwareInterface::needFDMetadata(qcamera_ch_type_enum_t channel_type)
10402  {
10403      //Note: Currently we only process ZSL channel
10404      bool value = false;
10405      if(channel_type == QCAMERA_CH_TYPE_ZSL){
10406          //check if FD requirement is enabled
10407          if(mParameters.isSnapshotFDNeeded() &&
10408             mParameters.isFaceDetectionEnabled()){
10409              value = true;
10410              LOGH("Face Detection metadata is required in ZSL mode.");
10411          }
10412      }
10413  
10414      return value;
10415  }
10416  
10417  /*===========================================================================
10418   * FUNCTION   : deferredWorkRoutine
10419   *
10420   * DESCRIPTION: data process routine that executes deferred tasks
10421   *
10422   * PARAMETERS :
10423   *   @data    : user data ptr (QCamera2HardwareInterface)
10424   *
10425   * RETURN     : None
10426   *==========================================================================*/
deferredWorkRoutine(void * obj)10427  void *QCamera2HardwareInterface::deferredWorkRoutine(void *obj)
10428  {
10429      int running = 1;
10430      int ret;
10431      uint8_t is_active = FALSE;
10432      int32_t job_status = 0;
10433  
10434      QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)obj;
10435      QCameraCmdThread *cmdThread = &pme->mDeferredWorkThread;
10436      cmdThread->setName("CAM_defrdWrk");
10437  
10438      do {
10439          do {
10440              ret = cam_sem_wait(&cmdThread->cmd_sem);
10441              if (ret != 0 && errno != EINVAL) {
10442                  LOGE("cam_sem_wait error (%s)",
10443                           strerror(errno));
10444                  return NULL;
10445              }
10446          } while (ret != 0);
10447  
10448          // we got notified about new cmd avail in cmd queue
10449          camera_cmd_type_t cmd = cmdThread->getCmd();
10450          LOGD("cmd: %d", cmd);
10451          switch (cmd) {
10452          case CAMERA_CMD_TYPE_START_DATA_PROC:
10453              LOGH("start data proc");
10454              is_active = TRUE;
10455              break;
10456          case CAMERA_CMD_TYPE_STOP_DATA_PROC:
10457              LOGH("stop data proc");
10458              is_active = FALSE;
10459              // signal cmd is completed
10460              cam_sem_post(&cmdThread->sync_sem);
10461              break;
10462          case CAMERA_CMD_TYPE_DO_NEXT_JOB:
10463              {
10464                  DefWork *dw =
10465                      reinterpret_cast<DefWork *>(pme->mCmdQueue.dequeue());
10466  
10467                  if ( NULL == dw ) {
10468                      LOGE("Invalid deferred work");
10469                      break;
10470                  }
10471  
10472                  switch( dw->cmd ) {
10473                  case CMD_DEF_ALLOCATE_BUFF:
10474                      {
10475                          QCameraChannel * pChannel = dw->args.allocArgs.ch;
10476  
10477                          if ( NULL == pChannel ) {
10478                              LOGE("Invalid deferred work channel");
10479                              job_status = BAD_VALUE;
10480                              break;
10481                          }
10482  
10483                          cam_stream_type_t streamType = dw->args.allocArgs.type;
10484                          LOGH("Deferred buffer allocation started for stream type: %d",
10485                                   streamType);
10486  
10487                          uint32_t iNumOfStreams = pChannel->getNumOfStreams();
10488                          QCameraStream *pStream = NULL;
10489                          for ( uint32_t i = 0; i < iNumOfStreams; ++i) {
10490                              pStream = pChannel->getStreamByIndex(i);
10491  
10492                              if ( NULL == pStream ) {
10493                                  job_status = BAD_VALUE;
10494                                  break;
10495                              }
10496  
10497                              if ( pStream->isTypeOf(streamType)) {
10498                                  if ( pStream->allocateBuffers() ) {
10499                                      LOGE("Error allocating buffers !!!");
10500                                      job_status =  NO_MEMORY;
10501                                      pme->sendEvtNotify(CAMERA_MSG_ERROR,
10502                                              CAMERA_ERROR_UNKNOWN, 0);
10503                                  }
10504                                  break;
10505                              }
10506                          }
10507                      }
10508                      break;
10509                  case CMD_DEF_PPROC_START:
10510                      {
10511                          int32_t ret = pme->getDefJobStatus(pme->mInitPProcJob);
10512                          if (ret != NO_ERROR) {
10513                              job_status = ret;
10514                              LOGE("PPROC Start failed");
10515                              pme->sendEvtNotify(CAMERA_MSG_ERROR,
10516                                      CAMERA_ERROR_UNKNOWN, 0);
10517                              break;
10518                          }
10519                          QCameraChannel * pChannel = dw->args.pprocArgs;
10520                          assert(pChannel);
10521  
10522                          if (pme->m_postprocessor.start(pChannel) != NO_ERROR) {
10523                              LOGE("cannot start postprocessor");
10524                              job_status = BAD_VALUE;
10525                              pme->sendEvtNotify(CAMERA_MSG_ERROR,
10526                                      CAMERA_ERROR_UNKNOWN, 0);
10527                          }
10528                      }
10529                      break;
10530                  case CMD_DEF_METADATA_ALLOC:
10531                      {
10532                          int32_t ret = pme->getDefJobStatus(pme->mParamAllocJob);
10533                          if (ret != NO_ERROR) {
10534                              job_status = ret;
10535                              LOGE("Metadata alloc failed");
10536                              pme->sendEvtNotify(CAMERA_MSG_ERROR,
10537                                      CAMERA_ERROR_UNKNOWN, 0);
10538                              break;
10539                          }
10540                          pme->mMetadataMem = new QCameraMetadataStreamMemory(
10541                                  QCAMERA_ION_USE_CACHE);
10542  
10543                          if (pme->mMetadataMem == NULL) {
10544                              LOGE("Unable to allocate metadata buffers");
10545                              job_status = BAD_VALUE;
10546                              pme->sendEvtNotify(CAMERA_MSG_ERROR,
10547                                      CAMERA_ERROR_UNKNOWN, 0);
10548                          } else {
10549                              int32_t rc = pme->mMetadataMem->allocate(
10550                                      dw->args.metadataAllocArgs.bufferCnt,
10551                                      dw->args.metadataAllocArgs.size);
10552                              if (rc < 0) {
10553                                  delete pme->mMetadataMem;
10554                                  pme->mMetadataMem = NULL;
10555                              }
10556                          }
10557                       }
10558                       break;
10559                  case CMD_DEF_CREATE_JPEG_SESSION:
10560                      {
10561                          QCameraChannel * pChannel = dw->args.pprocArgs;
10562                          assert(pChannel);
10563  
10564                          int32_t ret = pme->getDefJobStatus(pme->mReprocJob);
10565                          if (ret != NO_ERROR) {
10566                              job_status = ret;
10567                              LOGE("Jpeg create failed");
10568                              break;
10569                          }
10570  
10571                          if (pme->m_postprocessor.createJpegSession(pChannel)
10572                              != NO_ERROR) {
10573                              LOGE("cannot create JPEG session");
10574                              job_status = UNKNOWN_ERROR;
10575                              pme->sendEvtNotify(CAMERA_MSG_ERROR,
10576                                      CAMERA_ERROR_UNKNOWN, 0);
10577                          }
10578                      }
10579                      break;
10580                  case CMD_DEF_PPROC_INIT:
10581                      {
10582                          int32_t rc = NO_ERROR;
10583  
10584                          jpeg_encode_callback_t jpegEvtHandle =
10585                                  dw->args.pprocInitArgs.jpeg_cb;
10586                          void* user_data = dw->args.pprocInitArgs.user_data;
10587                          QCameraPostProcessor *postProcessor =
10588                                  &(pme->m_postprocessor);
10589                          uint32_t cameraId = pme->mCameraId;
10590                          cam_capability_t *capability =
10591                                  gCamCapability[cameraId];
10592                          cam_padding_info_t padding_info;
10593                          cam_padding_info_t& cam_capability_padding_info =
10594                                  capability->padding_info;
10595  
10596                          if(!pme->mJpegClientHandle) {
10597                              rc = pme->initJpegHandle();
10598                              if (rc != NO_ERROR) {
10599                                  LOGE("Error!! creating JPEG handle failed");
10600                                  job_status = UNKNOWN_ERROR;
10601                                  pme->sendEvtNotify(CAMERA_MSG_ERROR,
10602                                          CAMERA_ERROR_UNKNOWN, 0);
10603                                  break;
10604                              }
10605                          }
10606                          LOGH("mJpegClientHandle : %d", pme->mJpegClientHandle);
10607  
10608                          rc = postProcessor->setJpegHandle(&pme->mJpegHandle,
10609                                  &pme->mJpegMpoHandle,
10610                                  pme->mJpegClientHandle);
10611                          if (rc != 0) {
10612                              LOGE("Error!! set JPEG handle failed");
10613                              job_status = UNKNOWN_ERROR;
10614                              pme->sendEvtNotify(CAMERA_MSG_ERROR,
10615                                      CAMERA_ERROR_UNKNOWN, 0);
10616                              break;
10617                          }
10618  
10619                          /* get max pic size for jpeg work buf calculation*/
10620                          rc = postProcessor->init(jpegEvtHandle, user_data);
10621  
10622                          if (rc != NO_ERROR) {
10623                              LOGE("cannot init postprocessor");
10624                              job_status = UNKNOWN_ERROR;
10625                              pme->sendEvtNotify(CAMERA_MSG_ERROR,
10626                                      CAMERA_ERROR_UNKNOWN, 0);
10627                              break;
10628                          }
10629  
10630                          // update padding info from jpeg
10631                          postProcessor->getJpegPaddingReq(padding_info);
10632                          if (cam_capability_padding_info.width_padding <
10633                                  padding_info.width_padding) {
10634                              cam_capability_padding_info.width_padding =
10635                                      padding_info.width_padding;
10636                          }
10637                          if (cam_capability_padding_info.height_padding <
10638                                  padding_info.height_padding) {
10639                              cam_capability_padding_info.height_padding =
10640                                      padding_info.height_padding;
10641                          }
10642                          if (cam_capability_padding_info.plane_padding !=
10643                                  padding_info.plane_padding) {
10644                              cam_capability_padding_info.plane_padding =
10645                                      mm_stream_calc_lcm(
10646                                      cam_capability_padding_info.plane_padding,
10647                                      padding_info.plane_padding);
10648                          }
10649                          if (cam_capability_padding_info.offset_info.offset_x
10650                                  != padding_info.offset_info.offset_x) {
10651                              cam_capability_padding_info.offset_info.offset_x =
10652                                      mm_stream_calc_lcm (
10653                                      cam_capability_padding_info.offset_info.offset_x,
10654                                      padding_info.offset_info.offset_x);
10655                          }
10656                          if (cam_capability_padding_info.offset_info.offset_y
10657                                  != padding_info.offset_info.offset_y) {
10658                              cam_capability_padding_info.offset_info.offset_y =
10659                              mm_stream_calc_lcm (
10660                                      cam_capability_padding_info.offset_info.offset_y,
10661                                      padding_info.offset_info.offset_y);
10662                          }
10663                      }
10664                      break;
10665                  case CMD_DEF_PARAM_ALLOC:
10666                      {
10667                          int32_t rc = NO_ERROR;
10668                          if (pme->isDualCamera()) {
10669                              rc = pme->mParameters.allocate(MM_CAMERA_MAX_CAM_CNT);
10670                          } else {
10671                              rc = pme->mParameters.allocate();
10672                          }
10673                          // notify routine would not be initialized by this time.
10674                          // So, just update error job status
10675                          if (rc != NO_ERROR) {
10676                              job_status = rc;
10677                              LOGE("Param allocation failed");
10678                              break;
10679                          }
10680                      }
10681                      break;
10682                  case CMD_DEF_PARAM_INIT:
10683                      {
10684                          int32_t rc = pme->getDefJobStatus(pme->mParamAllocJob);
10685                          if (rc != NO_ERROR) {
10686                              job_status = rc;
10687                              LOGE("Param init failed");
10688                              pme->sendEvtNotify(CAMERA_MSG_ERROR,
10689                                      CAMERA_ERROR_UNKNOWN, 0);
10690                              break;
10691                          }
10692  
10693                          uint32_t camId = pme->mCameraId;
10694                          cam_capability_t * cap = gCamCapability[camId];
10695  
10696                          if (pme->mCameraHandle == NULL) {
10697                              LOGE("Camera handle is null");
10698                              job_status = BAD_VALUE;
10699                              pme->sendEvtNotify(CAMERA_MSG_ERROR,
10700                                      CAMERA_ERROR_UNKNOWN, 0);
10701                              break;
10702                          }
10703  
10704                          // Now PostProc need calibration data as initialization
10705                          // time for jpeg_open and calibration data is a
10706                          // get param for now, so params needs to be initialized
10707                          // before postproc init
10708                          rc = pme->mParameters.init(cap,
10709                                  pme->mCameraHandle,
10710                                  pme, pme->m_pFovControl);
10711                          if (rc != 0) {
10712                              job_status = UNKNOWN_ERROR;
10713                              LOGE("Parameter Initialization failed");
10714                              pme->sendEvtNotify(CAMERA_MSG_ERROR,
10715                                      CAMERA_ERROR_UNKNOWN, 0);
10716                              break;
10717                          }
10718  
10719                          // Get related cam calibration only in
10720                          // dual camera mode
10721                          if ((pme->getRelatedCamSyncInfo()->sync_control ==
10722                                  CAM_SYNC_RELATED_SENSORS_ON) || pme->isDualCamera()){
10723                              rc = pme->mParameters.getRelatedCamCalibration(
10724                                  &(pme->mJpegMetadata.otp_calibration_data));
10725                              LOGD("Dumping Calibration Data Version Id %f rc %d",
10726                                      pme->mJpegMetadata.otp_calibration_data.calibration_format_version,
10727                                      rc);
10728                              if (rc != 0) {
10729                                  job_status = UNKNOWN_ERROR;
10730                                  LOGE("getRelatedCamCalibration failed");
10731                                  pme->sendEvtNotify(CAMERA_MSG_ERROR,
10732                                          CAMERA_ERROR_UNKNOWN, 0);
10733                                  break;
10734                              }
10735                              pme->m_bRelCamCalibValid = true;
10736                          }
10737  
10738                          pme->mJpegMetadata.sensor_mount_angle =
10739                              cap->sensor_mount_angle;
10740                          pme->mJpegMetadata.default_sensor_flip = FLIP_NONE;
10741  
10742                          pme->mParameters.setMinPpMask(
10743                              cap->qcom_supported_feature_mask);
10744                          pme->mExifParams.debug_params =
10745                                  (mm_jpeg_debug_exif_params_t *)
10746                                  malloc(sizeof(mm_jpeg_debug_exif_params_t));
10747                          if (!pme->mExifParams.debug_params) {
10748                              LOGE("Out of Memory. Allocation failed for "
10749                                      "3A debug exif params");
10750                              job_status = NO_MEMORY;
10751                              pme->sendEvtNotify(CAMERA_MSG_ERROR,
10752                                      CAMERA_ERROR_UNKNOWN, 0);
10753                              break;
10754                          }
10755                          memset(pme->mExifParams.debug_params, 0,
10756                                  sizeof(mm_jpeg_debug_exif_params_t));
10757                      }
10758                      break;
10759                  case CMD_DEF_GENERIC:
10760                      {
10761                          BackgroundTask *bgTask = dw->args.genericArgs;
10762                          job_status = bgTask->bgFunction(bgTask->bgArgs);
10763                      }
10764                      break;
10765                  default:
10766                      LOGE("Incorrect command : %d", dw->cmd);
10767                  }
10768  
10769                  pme->dequeueDeferredWork(dw, job_status);
10770              }
10771              break;
10772          case CAMERA_CMD_TYPE_EXIT:
10773              running = 0;
10774              break;
10775          default:
10776              break;
10777          }
10778      } while (running);
10779  
10780      return NULL;
10781  }
10782  
10783  /*===========================================================================
10784   * FUNCTION   : queueDeferredWork
10785   *
10786   * DESCRIPTION: function which queues deferred tasks
10787   *
10788   * PARAMETERS :
10789   *   @cmd     : deferred task
10790   *   @args    : deferred task arguments
10791   *
10792   * RETURN     : job id of deferred job
10793   *            : 0 in case of error
10794   *==========================================================================*/
queueDeferredWork(DeferredWorkCmd cmd,DeferWorkArgs args)10795  uint32_t QCamera2HardwareInterface::queueDeferredWork(DeferredWorkCmd cmd,
10796                                                        DeferWorkArgs args)
10797  {
10798      Mutex::Autolock l(mDefLock);
10799      for (int32_t i = 0; i < MAX_ONGOING_JOBS; ++i) {
10800          if (mDefOngoingJobs[i].mDefJobId == 0) {
10801              DefWork *dw = new DefWork(cmd, sNextJobId, args);
10802              if (!dw) {
10803                  LOGE("out of memory.");
10804                  return 0;
10805              }
10806              if (mCmdQueue.enqueue(dw)) {
10807                  mDefOngoingJobs[i].mDefJobId = sNextJobId++;
10808                  mDefOngoingJobs[i].mDefJobStatus = 0;
10809                  if (sNextJobId == 0) { // handle overflow
10810                      sNextJobId = 1;
10811                  }
10812                  mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB,
10813                          FALSE,
10814                          FALSE);
10815                  return mDefOngoingJobs[i].mDefJobId;
10816              } else {
10817                  LOGD("Command queue not active! cmd = %d", cmd);
10818                  delete dw;
10819                  return 0;
10820              }
10821          }
10822      }
10823      return 0;
10824  }
10825  
10826  /*===========================================================================
10827   * FUNCTION   : initJpegHandle
10828   *
10829   * DESCRIPTION: Opens JPEG client and gets a handle.
10830   *                     Sends Dual cam calibration info if present
10831   *
10832   * RETURN     : int32_t type of status
10833   *              NO_ERROR  -- success
10834   *              none-zero failure code
10835   *==========================================================================*/
initJpegHandle()10836  int32_t QCamera2HardwareInterface::initJpegHandle() {
10837      // Check if JPEG client handle is present
10838      LOGH("E");
10839      if(!mJpegClientHandle) {
10840          mm_dimension max_size = {0, 0};
10841          cam_dimension_t size;
10842  
10843          mParameters.getMaxPicSize(size);
10844          max_size.w = size.width;
10845          max_size.h = size.height;
10846  
10847          if (getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
10848              if (m_bRelCamCalibValid) {
10849                  mJpegClientHandle = jpeg_open(&mJpegHandle, &mJpegMpoHandle,
10850                          max_size, &mJpegMetadata);
10851              } else {
10852                  mJpegClientHandle =  jpeg_open(&mJpegHandle, &mJpegMpoHandle,
10853                          max_size, NULL);
10854              }
10855          } else {
10856              mJpegClientHandle = jpeg_open(&mJpegHandle, NULL, max_size, NULL);
10857          }
10858          if (!mJpegClientHandle) {
10859              LOGE("Error !! jpeg_open failed!! ");
10860              return UNKNOWN_ERROR;
10861          }
10862          // Set JPEG initialized as true to signify that this camera
10863          // has initialized the handle
10864          mJpegHandleOwner = true;
10865      }
10866      LOGH("X mJpegHandleOwner: %d, mJpegClientHandle: %d camera id: %d",
10867               mJpegHandleOwner, mJpegClientHandle, mCameraId);
10868      return NO_ERROR;
10869  }
10870  
10871  /*===========================================================================
10872   * FUNCTION   : deinitJpegHandle
10873   *
10874   * DESCRIPTION: Closes JPEG client using handle
10875   *
10876   * RETURN     : int32_t type of status
10877   *              NO_ERROR  -- success
10878   *              none-zero failure code
10879   *==========================================================================*/
deinitJpegHandle()10880  int32_t QCamera2HardwareInterface::deinitJpegHandle() {
10881      int32_t rc = NO_ERROR;
10882      LOGH("E");
10883      // Check if JPEG client handle is present and inited by this camera
10884      if(mJpegHandleOwner && mJpegClientHandle) {
10885          rc = mJpegHandle.close(mJpegClientHandle);
10886          if (rc != NO_ERROR) {
10887              LOGE("Error!! Closing mJpegClientHandle: %d failed",
10888                       mJpegClientHandle);
10889          }
10890          memset(&mJpegHandle, 0, sizeof(mJpegHandle));
10891          memset(&mJpegMpoHandle, 0, sizeof(mJpegMpoHandle));
10892          mJpegHandleOwner = false;
10893      }
10894      mJpegClientHandle = 0;
10895      LOGH("X rc = %d", rc);
10896      return rc;
10897  }
10898  
10899  /*===========================================================================
10900   * FUNCTION   : setJpegHandleInfo
10901   *
10902   * DESCRIPTION: sets JPEG client handle info
10903   *
10904   * PARAMETERS:
10905   *                  @ops                    : JPEG ops
10906   *                  @mpo_ops             : Jpeg MPO ops
10907   *                  @pJpegClientHandle : o/p Jpeg Client Handle
10908   *
10909   * RETURN     : int32_t type of status
10910   *              NO_ERROR  -- success
10911   *              none-zero failure code
10912   *==========================================================================*/
setJpegHandleInfo(mm_jpeg_ops_t * ops,mm_jpeg_mpo_ops_t * mpo_ops,uint32_t pJpegClientHandle)10913  int32_t QCamera2HardwareInterface::setJpegHandleInfo(mm_jpeg_ops_t *ops,
10914          mm_jpeg_mpo_ops_t *mpo_ops, uint32_t pJpegClientHandle) {
10915  
10916      if (pJpegClientHandle && ops && mpo_ops) {
10917          LOGH("Setting JPEG client handle %d",
10918                  pJpegClientHandle);
10919          memcpy(&mJpegHandle, ops, sizeof(mm_jpeg_ops_t));
10920          memcpy(&mJpegMpoHandle, mpo_ops, sizeof(mm_jpeg_mpo_ops_t));
10921          mJpegClientHandle = pJpegClientHandle;
10922          return NO_ERROR;
10923      }
10924      else {
10925          LOGE("Error!! No Handle found: %d",
10926                  pJpegClientHandle);
10927          return BAD_VALUE;
10928      }
10929  }
10930  
10931  /*===========================================================================
10932   * FUNCTION   : getJpegHandleInfo
10933   *
10934   * DESCRIPTION: gets JPEG client handle info
10935   *
10936   * PARAMETERS:
10937   *                  @ops                    : JPEG ops
10938   *                  @mpo_ops             : Jpeg MPO ops
10939   *                  @pJpegClientHandle : o/p Jpeg Client Handle
10940   *
10941   * RETURN     : int32_t type of status
10942   *              NO_ERROR  -- success
10943   *              none-zero failure code
10944   *==========================================================================*/
getJpegHandleInfo(mm_jpeg_ops_t * ops,mm_jpeg_mpo_ops_t * mpo_ops,uint32_t * pJpegClientHandle)10945  int32_t QCamera2HardwareInterface::getJpegHandleInfo(mm_jpeg_ops_t *ops,
10946          mm_jpeg_mpo_ops_t *mpo_ops, uint32_t *pJpegClientHandle) {
10947  
10948      if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
10949          LOGE("Init PProc Deferred work failed");
10950          return UNKNOWN_ERROR;
10951      }
10952      // Copy JPEG ops if present
10953      if (ops && mpo_ops && pJpegClientHandle) {
10954          memcpy(ops, &mJpegHandle, sizeof(mm_jpeg_ops_t));
10955          memcpy(mpo_ops, &mJpegMpoHandle, sizeof(mm_jpeg_mpo_ops_t));
10956          *pJpegClientHandle = mJpegClientHandle;
10957          LOGH("Getting JPEG client handle %d",
10958                  pJpegClientHandle);
10959          return NO_ERROR;
10960      } else {
10961          return BAD_VALUE;
10962      }
10963  }
10964  
10965  /*===========================================================================
10966   * FUNCTION   : dequeueDeferredWork
10967   *
10968   * DESCRIPTION: function which dequeues deferred tasks
10969   *
10970   * PARAMETERS :
10971   *   @dw      : deferred work
10972   *   @jobStatus: deferred task job status
10973   *
10974   * RETURN     : int32_t type of status
10975   *              NO_ERROR  -- success
10976   *              none-zero failure code
10977   *==========================================================================*/
dequeueDeferredWork(DefWork * dw,int32_t jobStatus)10978  uint32_t QCamera2HardwareInterface::dequeueDeferredWork(DefWork* dw, int32_t jobStatus)
10979  {
10980      Mutex::Autolock l(mDefLock);
10981      for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) {
10982          if (mDefOngoingJobs[i].mDefJobId == dw->id) {
10983              if (jobStatus != NO_ERROR) {
10984                  mDefOngoingJobs[i].mDefJobStatus = jobStatus;
10985                  LOGH("updating job status %d for id %d",
10986                           jobStatus, dw->id);
10987              } else {
10988                  mDefOngoingJobs[i].mDefJobId = 0;
10989                  mDefOngoingJobs[i].mDefJobStatus = 0;
10990              }
10991              delete dw;
10992              mDefCond.broadcast();
10993              return NO_ERROR;
10994          }
10995      }
10996  
10997      return UNKNOWN_ERROR;
10998  }
10999  
11000  /*===========================================================================
11001   * FUNCTION   : getDefJobStatus
11002   *
11003   * DESCRIPTION: Gets if a deferred task is success/fail
11004   *
11005   * PARAMETERS :
11006   *   @job_id  : deferred task id
11007   *
11008   * RETURN     : NO_ERROR if the job success, otherwise false
11009   *
11010   * PRECONDITION : mDefLock is held by current thread
11011   *==========================================================================*/
getDefJobStatus(uint32_t & job_id)11012  int32_t QCamera2HardwareInterface::getDefJobStatus(uint32_t &job_id)
11013  {
11014      for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) {
11015          if (mDefOngoingJobs[i].mDefJobId == job_id) {
11016              if ( NO_ERROR != mDefOngoingJobs[i].mDefJobStatus ) {
11017                  LOGE("job_id (%d) was failed", job_id);
11018                  return mDefOngoingJobs[i].mDefJobStatus;
11019              }
11020              else
11021                  return NO_ERROR;
11022          }
11023      }
11024      return NO_ERROR;
11025  }
11026  
11027  
11028  /*===========================================================================
11029   * FUNCTION   : checkDeferredWork
11030   *
11031   * DESCRIPTION: checks if a deferred task is in progress
11032   *
11033   * PARAMETERS :
11034   *   @job_id  : deferred task id
11035   *
11036   * RETURN     : true if the task exists, otherwise false
11037   *
11038   * PRECONDITION : mDefLock is held by current thread
11039   *==========================================================================*/
checkDeferredWork(uint32_t & job_id)11040  bool QCamera2HardwareInterface::checkDeferredWork(uint32_t &job_id)
11041  {
11042      for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) {
11043          if (mDefOngoingJobs[i].mDefJobId == job_id) {
11044              return (NO_ERROR == mDefOngoingJobs[i].mDefJobStatus);
11045          }
11046      }
11047      return false;
11048  }
11049  
11050  /*===========================================================================
11051   * FUNCTION   : waitDeferredWork
11052   *
11053   * DESCRIPTION: waits for a deferred task to finish
11054   *
11055   * PARAMETERS :
11056   *   @job_id  : deferred task id
11057   *
11058   * RETURN     : int32_t type of status
11059   *              NO_ERROR  -- success
11060   *              none-zero failure code
11061   *==========================================================================*/
waitDeferredWork(uint32_t & job_id)11062  int32_t QCamera2HardwareInterface::waitDeferredWork(uint32_t &job_id)
11063  {
11064      Mutex::Autolock l(mDefLock);
11065  
11066      if (job_id == 0) {
11067          LOGD("Invalid job id %d", job_id);
11068          return NO_ERROR;
11069      }
11070  
11071      while (checkDeferredWork(job_id) == true ) {
11072          mDefCond.waitRelative(mDefLock, CAMERA_DEFERRED_THREAD_TIMEOUT);
11073      }
11074      return getDefJobStatus(job_id);
11075  }
11076  
11077  /*===========================================================================
11078   * FUNCTION   : scheduleBackgroundTask
11079   *
11080   * DESCRIPTION: Run a requested task in the deferred thread
11081   *
11082   * PARAMETERS :
11083   *   @bgTask  : Task to perform in the background
11084   *
11085   * RETURN     : job id of deferred job
11086   *            : 0 in case of error
11087   *==========================================================================*/
scheduleBackgroundTask(BackgroundTask * bgTask)11088  uint32_t QCamera2HardwareInterface::scheduleBackgroundTask(BackgroundTask* bgTask)
11089  {
11090      DeferWorkArgs args;
11091      memset(&args, 0, sizeof(DeferWorkArgs));
11092      args.genericArgs = bgTask;
11093  
11094      return queueDeferredWork(CMD_DEF_GENERIC, args);
11095  }
11096  
11097  /*===========================================================================
11098   * FUNCTION   : waitForBackgroundTask
11099   *
11100   * DESCRIPTION: Wait for a background task to complete
11101   *
11102   * PARAMETERS :
11103   *   @taskId  : Task id to wait for
11104   *
11105   * RETURN     : int32_t type of status
11106   *              NO_ERROR  -- success
11107   *              none-zero failure code
11108   *==========================================================================*/
waitForBackgroundTask(uint32_t & taskId)11109  int32_t QCamera2HardwareInterface::waitForBackgroundTask(uint32_t& taskId)
11110  {
11111      return waitDeferredWork(taskId);
11112  }
11113  
11114  /*===========================================================================
11115   * FUNCTION   : needDeferedAllocation
11116   *
11117   * DESCRIPTION: Function to decide background task for streams
11118   *
11119   * PARAMETERS :
11120   *   @stream_type  : stream type
11121   *
11122   * RETURN     : true - if background task is needed
11123   *              false -  if background task is NOT needed
11124   *==========================================================================*/
needDeferred(cam_stream_type_t stream_type)11125  bool QCamera2HardwareInterface::needDeferred(cam_stream_type_t stream_type)
11126  {
11127      if ((stream_type == CAM_STREAM_TYPE_PREVIEW && mPreviewWindow == NULL)
11128              || (stream_type == CAM_STREAM_TYPE_ANALYSIS)) {
11129          return FALSE;
11130      }
11131  
11132      if ((stream_type == CAM_STREAM_TYPE_RAW)
11133              && (mParameters.getofflineRAW() && !mParameters.getQuadraCfa())) {
11134          return FALSE;
11135      }
11136  
11137      if ((stream_type == CAM_STREAM_TYPE_SNAPSHOT)
11138              && (!mParameters.getRecordingHintValue())){
11139          return TRUE;
11140      }
11141  
11142      if ((stream_type == CAM_STREAM_TYPE_PREVIEW)
11143              || (stream_type == CAM_STREAM_TYPE_METADATA)
11144              || (stream_type == CAM_STREAM_TYPE_RAW)
11145              || (stream_type == CAM_STREAM_TYPE_POSTVIEW)) {
11146          return TRUE;
11147      }
11148  
11149      if (stream_type == CAM_STREAM_TYPE_VIDEO) {
11150          return FALSE;
11151      }
11152      return FALSE;
11153  }
11154  
11155  /*===========================================================================
11156   * FUNCTION   : needSyncCB
11157   *
11158   * DESCRIPTION: Decide syncronous callback per stream
11159   *
11160   * PARAMETERS :
11161   *  @stream_type: stream type
11162   *
11163   * RETURN     : true - if background task is needed
11164   *              false -  if background task is NOT needed
11165   *==========================================================================*/
needSyncCB(cam_stream_type_t stream_type)11166  bool QCamera2HardwareInterface::needSyncCB(cam_stream_type_t stream_type)
11167  {
11168  #ifdef TARGET_TS_MAKEUP
11169      int whiteLevel, cleanLevel;
11170      if(mParameters.getTsMakeupInfo(whiteLevel, cleanLevel) == TRUE) {
11171          return FALSE;
11172      }
11173  #endif
11174  
11175      char value[PROPERTY_VALUE_MAX];
11176      property_get("persist.camera.preview.sync_cb", value, "1");
11177      if ((atoi(value) == 1) && (stream_type == CAM_STREAM_TYPE_PREVIEW)) {
11178          return TRUE;
11179      }
11180      return FALSE;
11181  }
11182  
11183  /*===========================================================================
11184   * FUNCTION   : isRegularCapture
11185   *
11186   * DESCRIPTION: Check configuration for regular catpure
11187   *
11188   * PARAMETERS :
11189   *
11190   * RETURN     : true - regular capture
11191   *              false - other type of capture
11192   *==========================================================================*/
isRegularCapture()11193  bool QCamera2HardwareInterface::isRegularCapture()
11194  {
11195      bool ret = false;
11196  
11197      if (numOfSnapshotsExpected() == 1 &&
11198          !isLongshotEnabled() &&
11199          !mParameters.isHDREnabled() &&
11200          !mParameters.getRecordingHintValue() &&
11201          !isZSLMode() && (!mParameters.getofflineRAW()|| mParameters.getQuadraCfa())) {
11202              ret = true;
11203      }
11204      return ret;
11205  }
11206  
11207  /*===========================================================================
11208   * FUNCTION   : needOfflineReprocessing
11209   *
11210   * DESCRIPTION: Check for offline reprocessing
11211   *
11212   * PARAMETERS :
11213   *
11214   * RETURN     : true - regular capture
11215   *              false - other type of capture
11216   *==========================================================================*/
needOfflineReprocessing()11217  bool QCamera2HardwareInterface::needOfflineReprocessing()
11218  {
11219      bool ret = false;
11220      if (isRegularCapture()
11221              || isDualCamera()) {
11222          ret = true;
11223      }
11224      return ret;
11225  }
11226  
11227  /*===========================================================================
11228   * FUNCTION   : getLogLevel
11229   *
11230   * DESCRIPTION: Reads the log level property into a variable
11231   *
11232   * PARAMETERS :
11233   *   None
11234   *
11235   * RETURN     :
11236   *   None
11237   *==========================================================================*/
getLogLevel()11238  void QCamera2HardwareInterface::getLogLevel()
11239  {
11240      char prop[PROPERTY_VALUE_MAX];
11241  
11242      property_get("persist.camera.kpi.debug", prop, "0");
11243      gKpiDebugLevel = atoi(prop);
11244      return;
11245  }
11246  
11247  /*===========================================================================
11248   * FUNCTION   : getSensorType
11249   *
11250   * DESCRIPTION: Returns the type of sensor being used whether YUV or Bayer
11251   *
11252   * PARAMETERS :
11253   *   None
11254   *
11255   * RETURN     : Type of sensor - bayer or YUV
11256   *
11257   *==========================================================================*/
getSensorType()11258  cam_sensor_t QCamera2HardwareInterface::getSensorType()
11259  {
11260      return gCamCapability[mCameraId]->sensor_type.sens_type;
11261  }
11262  
11263  /*===========================================================================
11264   * FUNCTION   : startRAWChannel
11265   *
11266   * DESCRIPTION: start RAW Channel
11267   *
11268   * PARAMETERS :
11269   *   @pChannel  : Src channel to link this RAW channel.
11270   *
11271   * RETURN     : int32_t type of status
11272   *              NO_ERROR  -- success
11273   *              none-zero failure code
11274   *==========================================================================*/
startRAWChannel(QCameraChannel * pMetaChannel)11275  int32_t QCamera2HardwareInterface::startRAWChannel(QCameraChannel *pMetaChannel)
11276  {
11277      int32_t rc = NO_ERROR;
11278      QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_RAW];
11279      if ((NULL != pChannel) && (mParameters.getofflineRAW())) {
11280          // Find and try to link a metadata stream from preview channel
11281          QCameraStream *pMetaStream = NULL;
11282  
11283          if (pMetaChannel != NULL) {
11284              uint32_t streamNum = pMetaChannel->getNumOfStreams();
11285              QCameraStream *pStream = NULL;
11286              for (uint32_t i = 0 ; i < streamNum ; i++ ) {
11287                  pStream = pMetaChannel->getStreamByIndex(i);
11288                  if ((NULL != pStream) &&
11289                          (CAM_STREAM_TYPE_METADATA == pStream->getMyType())) {
11290                      pMetaStream = pStream;
11291                      break;
11292                  }
11293              }
11294  
11295              if (NULL != pMetaStream) {
11296                  rc = pChannel->linkStream(pMetaChannel, pMetaStream);
11297                  if (NO_ERROR != rc) {
11298                      LOGE("Metadata stream link failed %d", rc);
11299                  }
11300              }
11301          }
11302          rc = pChannel->start();
11303      }
11304      return rc;
11305  }
11306  
11307  /*===========================================================================
11308   * FUNCTION   : startRecording
11309   *
11310   * DESCRIPTION: start recording impl
11311   *
11312   * PARAMETERS : none
11313   *
11314   * RETURN     : int32_t type of status
11315   *              NO_ERROR  -- success
11316   *              none-zero failure code
11317   *==========================================================================*/
stopRAWChannel()11318  int32_t QCamera2HardwareInterface::stopRAWChannel()
11319  {
11320      int32_t rc = NO_ERROR;
11321      rc = stopChannel(QCAMERA_CH_TYPE_RAW);
11322      return rc;
11323  }
11324  
11325  /*===========================================================================
11326   * FUNCTION   : isLowPowerMode
11327   *
11328   * DESCRIPTION: Returns TRUE if low power mode settings are to be applied for video recording
11329   *
11330   * PARAMETERS :
11331   *   None
11332   *
11333   * RETURN     : TRUE/FALSE
11334   *
11335   *==========================================================================*/
isLowPowerMode()11336  bool QCamera2HardwareInterface::isLowPowerMode()
11337  {
11338      cam_dimension_t dim;
11339      mParameters.getStreamDimension(CAM_STREAM_TYPE_VIDEO, dim);
11340  
11341      char prop[PROPERTY_VALUE_MAX];
11342      property_get("camera.lowpower.record.enable", prop, "0");
11343      int enable = atoi(prop);
11344  
11345      //Enable low power mode if :
11346      //1. Video resolution is 2k (2048x1080) or above and
11347      //2. camera.lowpower.record.enable is set
11348  
11349      bool isLowpower = mParameters.getRecordingHintValue() && enable
11350              && ((dim.width * dim.height) >= (2048 * 1080));
11351      return isLowpower;
11352  }
11353  
11354  /*===========================================================================
11355   * FUNCTION   : getBootToMonoTimeOffset
11356   *
11357   * DESCRIPTION: Calculate offset that is used to convert from
11358   *              clock domain of boot to monotonic
11359   *
11360   * PARAMETERS :
11361   *   None
11362   *
11363   * RETURN     : clock offset between boottime and monotonic time.
11364   *
11365   *==========================================================================*/
getBootToMonoTimeOffset()11366  nsecs_t QCamera2HardwareInterface::getBootToMonoTimeOffset()
11367  {
11368      // try three times to get the clock offset, choose the one
11369      // with the minimum gap in measurements.
11370      const int tries = 3;
11371      nsecs_t bestGap, measured;
11372      for (int i = 0; i < tries; ++i) {
11373          const nsecs_t tmono = systemTime(SYSTEM_TIME_MONOTONIC);
11374          const nsecs_t tbase = systemTime(SYSTEM_TIME_BOOTTIME);
11375          const nsecs_t tmono2 = systemTime(SYSTEM_TIME_MONOTONIC);
11376          const nsecs_t gap = tmono2 - tmono;
11377          if (i == 0 || gap < bestGap) {
11378              bestGap = gap;
11379              measured = tbase - ((tmono + tmono2) >> 1);
11380          }
11381      }
11382      return measured;
11383  }
11384  
11385  /*===========================================================================
11386   * FUNCTION   : fillDualCameraFOVControl
11387   *
11388   * DESCRIPTION: Function to process FOV ctrl event from statemachine thread.
11389   *
11390   * PARAMETERS : none
11391   *
11392   * RETURN     : none
11393   *==========================================================================*/
fillDualCameraFOVControl()11394  void QCamera2HardwareInterface::fillDualCameraFOVControl()
11395  {
11396      qcamera_sm_internal_evt_payload_t *payload =
11397         (qcamera_sm_internal_evt_payload_t *)
11398         malloc(sizeof(qcamera_sm_internal_evt_payload_t));
11399      if (NULL != payload) {
11400          memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
11401          payload->evt_type = QCAMERA_INTERNAL_EVT_DUAL_CAMERA_FOV_CONTROL;
11402          int32_t rc = processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
11403          if (rc != NO_ERROR) {
11404              LOGE("processEvt Dual camera fill FOV control failed");
11405              free(payload);
11406              payload = NULL;
11407          }
11408      } else {
11409          LOGE("No memory for Dual camera fill FOV control event");
11410      }
11411  }
11412  
11413  }; // namespace qcamera
11414