• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (c) 2012-2016, 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 {
1689 #ifdef TARGET_TS_MAKEUP
1690     memset(&mFaceRect, -1, sizeof(mFaceRect));
1691 #endif
1692     getLogLevel();
1693     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_QCAMERA2HWI);
1694     mCameraDevice.common.tag = HARDWARE_DEVICE_TAG;
1695     mCameraDevice.common.version = HARDWARE_DEVICE_API_VERSION(1, 0);
1696     mCameraDevice.common.close = close_camera_device;
1697     mCameraDevice.ops = &mCameraOps;
1698     mCameraDevice.priv = this;
1699 
1700     mDualCamera = is_dual_camera_by_idx(cameraId);
1701 
1702     pthread_mutex_init(&m_lock, NULL);
1703     pthread_cond_init(&m_cond, NULL);
1704 
1705     m_apiResultList = NULL;
1706 
1707     pthread_mutex_init(&m_evtLock, NULL);
1708     pthread_cond_init(&m_evtCond, NULL);
1709     memset(&m_evtResult, 0, sizeof(qcamera_api_result_t));
1710 
1711 
1712     pthread_mutex_init(&m_int_lock, NULL);
1713     pthread_cond_init(&m_int_cond, NULL);
1714 
1715     memset(m_channels, 0, sizeof(m_channels));
1716 
1717     memset(&mExifParams, 0, sizeof(mm_jpeg_exif_params_t));
1718 
1719     memset(m_BackendFileName, 0, QCAMERA_MAX_FILEPATH_LENGTH);
1720 
1721     memset(mDefOngoingJobs, 0, sizeof(mDefOngoingJobs));
1722     memset(&mJpegMetadata, 0, sizeof(mJpegMetadata));
1723     memset(&mJpegHandle, 0, sizeof(mJpegHandle));
1724     memset(&mJpegMpoHandle, 0, sizeof(mJpegMpoHandle));
1725 
1726     mDeferredWorkThread.launch(deferredWorkRoutine, this);
1727     mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_START_DATA_PROC, FALSE, FALSE);
1728 
1729     pthread_mutex_init(&mGrallocLock, NULL);
1730     mEnqueuedBuffers = 0;
1731     mFrameSkipStart = 0;
1732     mFrameSkipEnd = 0;
1733     mLastPreviewFrameID = 0;
1734 
1735     //Load and read GPU library.
1736     lib_surface_utils = NULL;
1737     LINK_get_surface_pixel_alignment = NULL;
1738     mSurfaceStridePadding = CAM_PAD_TO_32;
1739     lib_surface_utils = dlopen("libadreno_utils.so", RTLD_NOW);
1740     if (lib_surface_utils) {
1741         *(void **)&LINK_get_surface_pixel_alignment =
1742                 dlsym(lib_surface_utils, "get_gpu_pixel_alignment");
1743          if (LINK_get_surface_pixel_alignment) {
1744              mSurfaceStridePadding = LINK_get_surface_pixel_alignment();
1745          }
1746          dlclose(lib_surface_utils);
1747     }
1748 }
1749 
1750 /*===========================================================================
1751  * FUNCTION   : ~QCamera2HardwareInterface
1752  *
1753  * DESCRIPTION: destructor of QCamera2HardwareInterface
1754  *
1755  * PARAMETERS : none
1756  *
1757  * RETURN     : none
1758  *==========================================================================*/
~QCamera2HardwareInterface()1759 QCamera2HardwareInterface::~QCamera2HardwareInterface()
1760 {
1761     LOGH("E");
1762 
1763     mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_STOP_DATA_PROC, TRUE, TRUE);
1764     mDeferredWorkThread.exit();
1765 
1766     if (mMetadataMem != NULL) {
1767         delete mMetadataMem;
1768         mMetadataMem = NULL;
1769     }
1770 
1771     if (m_pFovControl) {
1772         delete m_pFovControl;
1773         m_pFovControl = NULL;
1774     }
1775 
1776     m_perfLockMgr.acquirePerfLock(PERF_LOCK_CLOSE_CAMERA);
1777     lockAPI();
1778     m_smThreadActive = false;
1779     unlockAPI();
1780     m_stateMachine.releaseThread();
1781     closeCamera();
1782     m_perfLockMgr.releasePerfLock(PERF_LOCK_CLOSE_CAMERA);
1783 
1784     pthread_mutex_destroy(&m_lock);
1785     pthread_cond_destroy(&m_cond);
1786     pthread_mutex_destroy(&m_evtLock);
1787     pthread_cond_destroy(&m_evtCond);
1788     pthread_mutex_destroy(&m_int_lock);
1789     pthread_cond_destroy(&m_int_cond);
1790     pthread_mutex_destroy(&mGrallocLock);
1791     LOGH("X");
1792 }
1793 
1794 /*===========================================================================
1795  * FUNCTION   : deferPPInit
1796  *
1797  * DESCRIPTION: Queue postproc init task to deferred thread
1798  *
1799  * PARAMETERS : none
1800  *
1801  * RETURN     : uint32_t job id of pproc init job
1802  *              0  -- failure
1803  *==========================================================================*/
deferPPInit()1804 uint32_t QCamera2HardwareInterface::deferPPInit()
1805 {
1806     // init pproc
1807     DeferWorkArgs args;
1808     DeferPProcInitArgs pprocInitArgs;
1809 
1810     memset(&args, 0, sizeof(DeferWorkArgs));
1811     memset(&pprocInitArgs, 0, sizeof(DeferPProcInitArgs));
1812 
1813     pprocInitArgs.jpeg_cb = jpegEvtHandle;
1814     pprocInitArgs.user_data = this;
1815     args.pprocInitArgs = pprocInitArgs;
1816 
1817     return queueDeferredWork(CMD_DEF_PPROC_INIT,
1818             args);
1819 }
1820 
1821 /*===========================================================================
1822  * FUNCTION   : openCamera
1823  *
1824  * DESCRIPTION: open camera
1825  *
1826  * PARAMETERS :
1827  *   @hw_device  : double ptr for camera device struct
1828  *
1829  * RETURN     : int32_t type of status
1830  *              NO_ERROR  -- success
1831  *              none-zero failure code
1832  *==========================================================================*/
openCamera(struct hw_device_t ** hw_device)1833 int QCamera2HardwareInterface::openCamera(struct hw_device_t **hw_device)
1834 {
1835     KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_OPENCAMERA);
1836     int rc = NO_ERROR;
1837     if (mCameraOpened) {
1838         *hw_device = NULL;
1839         LOGE("Permission Denied");
1840         return PERMISSION_DENIED;
1841     }
1842     LOGI("[KPI Perf]: E PROFILE_OPEN_CAMERA camera id %d",
1843             mCameraId);
1844 
1845     m_perfLockMgr.acquirePerfLock(PERF_LOCK_OPEN_CAMERA);
1846 
1847     rc = openCamera();
1848     if (rc == NO_ERROR){
1849         *hw_device = &mCameraDevice.common;
1850         if (m_thermalAdapter.init(this) != 0) {
1851           LOGW("Init thermal adapter failed");
1852         }
1853     }
1854     else
1855         *hw_device = NULL;
1856 
1857     LOGI("[KPI Perf]: X PROFILE_OPEN_CAMERA camera id %d, rc: %d",
1858             mCameraId, rc);
1859 
1860     return rc;
1861 }
1862 
1863 /*===========================================================================
1864  * FUNCTION   : openCamera
1865  *
1866  * DESCRIPTION: open camera
1867  *
1868  * PARAMETERS : none
1869  *
1870  * RETURN     : int32_t type of status
1871  *              NO_ERROR  -- success
1872  *              none-zero failure code
1873  *==========================================================================*/
openCamera()1874 int QCamera2HardwareInterface::openCamera()
1875 {
1876     int32_t rc = NO_ERROR;
1877     char value[PROPERTY_VALUE_MAX];
1878 
1879     if (mCameraHandle) {
1880         LOGE("Failure: Camera already opened");
1881         return ALREADY_EXISTS;
1882     }
1883 
1884     rc = QCameraFlash::getInstance().reserveFlashForCamera(mCameraId);
1885     if (rc < 0) {
1886         LOGE("Failed to reserve flash for camera id: %d",
1887                 mCameraId);
1888         return UNKNOWN_ERROR;
1889     }
1890 
1891     // alloc param buffer
1892     DeferWorkArgs args;
1893     memset(&args, 0, sizeof(args));
1894     mParamAllocJob = queueDeferredWork(CMD_DEF_PARAM_ALLOC, args);
1895     if (mParamAllocJob == 0) {
1896         LOGE("Failed queueing PARAM_ALLOC job");
1897         return -ENOMEM;
1898     }
1899 
1900     if (gCamCapability[mCameraId] != NULL) {
1901         // allocate metadata buffers
1902         DeferWorkArgs args;
1903         DeferMetadataAllocArgs metadataAllocArgs;
1904 
1905         memset(&args, 0, sizeof(args));
1906         memset(&metadataAllocArgs, 0, sizeof(metadataAllocArgs));
1907 
1908         uint32_t padding =
1909                 gCamCapability[mCameraId]->padding_info.plane_padding;
1910         metadataAllocArgs.size = PAD_TO_SIZE(sizeof(metadata_buffer_t),
1911                 padding);
1912         metadataAllocArgs.bufferCnt = CAMERA_MIN_METADATA_BUFFERS;
1913         args.metadataAllocArgs = metadataAllocArgs;
1914 
1915         mMetadataAllocJob = queueDeferredWork(CMD_DEF_METADATA_ALLOC, args);
1916         if (mMetadataAllocJob == 0) {
1917             LOGE("Failed to allocate metadata buffer");
1918             rc = -ENOMEM;
1919             goto error_exit1;
1920         }
1921 
1922         rc = camera_open((uint8_t)mCameraId, &mCameraHandle);
1923         if (rc) {
1924             LOGE("camera_open failed. rc = %d, mCameraHandle = %p",
1925                      rc, mCameraHandle);
1926             goto error_exit2;
1927         }
1928 
1929         mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle,
1930                 camEvtHandle,
1931                 (void *) this);
1932     } else {
1933         LOGH("Capabilities not inited, initializing now.");
1934 
1935         rc = camera_open((uint8_t)mCameraId, &mCameraHandle);
1936         if (rc) {
1937             LOGE("camera_open failed. rc = %d, mCameraHandle = %p",
1938                      rc, mCameraHandle);
1939             goto error_exit2;
1940         }
1941 
1942         if(NO_ERROR != initCapabilities(mCameraId,mCameraHandle)) {
1943             LOGE("initCapabilities failed.");
1944             rc = UNKNOWN_ERROR;
1945             goto error_exit3;
1946         }
1947 
1948         mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle,
1949                 camEvtHandle,
1950                 (void *) this);
1951     }
1952 
1953     mActiveCamera = MM_CAMERA_TYPE_MAIN;
1954     if (isDualCamera()) {
1955         mActiveCamera |= MM_CAMERA_TYPE_AUX;
1956 
1957         // Create and initialize FOV-control object
1958         m_pFovControl = QCameraFOVControl::create(gCamCapability[mCameraId]->main_cam_cap,
1959                 gCamCapability[mCameraId]->aux_cam_cap);
1960         if (m_pFovControl) {
1961             *gCamCapability[mCameraId] = m_pFovControl->consolidateCapabilities(
1962                     gCamCapability[mCameraId]->main_cam_cap,
1963                     gCamCapability[mCameraId]->aux_cam_cap);
1964         } else {
1965             LOGE("FOV-control: Failed to create an object");
1966             rc = NO_MEMORY;
1967             goto error_exit3;
1968         }
1969     }
1970 
1971     // Init params in the background
1972     // 1. It's safe to queue init job, even if alloc job is not yet complete.
1973     // It will be queued to the same thread, so the alloc is guaranteed to
1974     // finish first.
1975     // 2. However, it is not safe to begin param init until after camera is
1976     // open. That is why we wait until after camera open completes to schedule
1977     // this task.
1978     memset(&args, 0, sizeof(args));
1979     mParamInitJob = queueDeferredWork(CMD_DEF_PARAM_INIT, args);
1980     if (mParamInitJob == 0) {
1981         LOGE("Failed queuing PARAM_INIT job");
1982         rc = -ENOMEM;
1983         goto error_exit3;
1984     }
1985 
1986     mCameraOpened = true;
1987 
1988     //Notify display HAL that a camera session is active.
1989     //But avoid calling the same during bootup because camera service might open/close
1990     //cameras at boot time during its initialization and display service will also internally
1991     //wait for camera service to initialize first while calling this display API, resulting in a
1992     //deadlock situation. Since boot time camera open/close calls are made only to fetch
1993     //capabilities, no need of this display bw optimization.
1994     //Use "service.bootanim.exit" property to know boot status.
1995     property_get("service.bootanim.exit", value, "0");
1996     if (atoi(value) == 1) {
1997         pthread_mutex_lock(&gCamLock);
1998         if (gNumCameraSessions++ == 0) {
1999             setCameraLaunchStatus(true);
2000         }
2001         pthread_mutex_unlock(&gCamLock);
2002     }
2003 
2004     // Setprop to decide the time source (whether boottime or monotonic).
2005     // By default, use monotonic time.
2006     property_get("persist.camera.time.monotonic", value, "1");
2007     mBootToMonoTimestampOffset = 0;
2008     if (atoi(value) == 1) {
2009         // if monotonic is set, then need to use time in monotonic.
2010         // So, Measure the clock offset between BOOTTIME and MONOTONIC
2011         // The clock domain source for ISP is BOOTTIME and
2012         // for Video/display is MONOTONIC
2013         // The below offset is used to convert from clock domain of other subsystem
2014         // (video/hardware composer) to that of camera. Assumption is that this
2015         // offset won't change during the life cycle of the camera device. In other
2016         // words, camera device shouldn't be open during CPU suspend.
2017         mBootToMonoTimestampOffset = getBootToMonoTimeOffset();
2018     }
2019     LOGH("mBootToMonoTimestampOffset = %lld", mBootToMonoTimestampOffset);
2020 
2021     memset(value, 0, sizeof(value));
2022     property_get("persist.camera.depth.focus.cb", value, "1");
2023     bDepthAFCallbacks = atoi(value);
2024 
2025     memset(value, 0, sizeof(value));
2026     property_get("persist.camera.cache.optimize", value, "1");
2027     m_bOptimizeCacheOps = atoi(value);
2028 
2029     return NO_ERROR;
2030 
2031 error_exit3:
2032     if(mJpegClientHandle) {
2033         deinitJpegHandle();
2034     }
2035     mCameraHandle->ops->close_camera(mCameraHandle->camera_handle);
2036     mCameraHandle = NULL;
2037 error_exit2:
2038     waitDeferredWork(mMetadataAllocJob);
2039 error_exit1:
2040     waitDeferredWork(mParamAllocJob);
2041     return rc;
2042 
2043 }
2044 
2045 /*===========================================================================
2046  * FUNCTION   : bundleRelatedCameras
2047  *
2048  * DESCRIPTION: bundle cameras to enable syncing of cameras
2049  *
2050  * PARAMETERS :
2051  *   @sync        :indicates whether syncing is On or Off
2052  *
2053  * RETURN     : int32_t type of status
2054  *              NO_ERROR  -- success
2055  *              none-zero failure code
2056  *==========================================================================*/
bundleRelatedCameras(bool syncOn)2057 int QCamera2HardwareInterface::bundleRelatedCameras(bool syncOn)
2058 {
2059     int32_t rc = mParameters.bundleRelatedCameras(syncOn);
2060     if (rc != NO_ERROR) {
2061         LOGE("bundleRelatedCameras failed %d", rc);
2062         return rc;
2063     }
2064     return rc;
2065 }
2066 
2067 /*===========================================================================
2068  * FUNCTION   : getCameraSessionId
2069  *
2070  * DESCRIPTION: gets the backend session Id of this HWI instance
2071  *
2072  * PARAMETERS :
2073  *   @sessionid  : pointer to the output session id
2074  *
2075  * RETURN     : int32_t type of status
2076  *              NO_ERROR  -- success
2077  *              none-zero failure code
2078  *==========================================================================*/
getCameraSessionId(uint32_t * session_id)2079 int QCamera2HardwareInterface::getCameraSessionId(uint32_t* session_id)
2080 {
2081     int32_t rc = NO_ERROR;
2082 
2083     if(session_id != NULL) {
2084         rc = mCameraHandle->ops->get_session_id(mCameraHandle->camera_handle,
2085                 session_id);
2086         LOGD("Getting Camera Session Id %d", *session_id);
2087     } else {
2088         LOGE("Session Id is Null");
2089         return UNKNOWN_ERROR;
2090     }
2091     return rc;
2092 }
2093 
2094 /*===========================================================================
2095  * FUNCTION   : isFrameSyncEnabled
2096  *
2097  * DESCRIPTION: returns whether frame sync is enabled
2098  *
2099  * PARAMETERS : none
2100  *
2101  * RETURN     : bool indicating whether frame sync is enabled
2102  *==========================================================================*/
isFrameSyncEnabled(void)2103 bool QCamera2HardwareInterface::isFrameSyncEnabled(void)
2104 {
2105     return mParameters.isFrameSyncEnabled();
2106 }
2107 
2108 /*===========================================================================
2109  * FUNCTION   : setFrameSyncEnabled
2110  *
2111  * DESCRIPTION: sets whether frame sync is enabled
2112  *
2113  * PARAMETERS :
2114  *   @enable  : flag whether to enable or disable frame sync
2115  *
2116  * RETURN     : int32_t type of status
2117  *              NO_ERROR  -- success
2118  *              none-zero failure code
2119  *==========================================================================*/
setFrameSyncEnabled(bool enable)2120 int32_t QCamera2HardwareInterface::setFrameSyncEnabled(bool enable)
2121 {
2122     return mParameters.setFrameSyncEnabled(enable);
2123 }
2124 
2125 /*===========================================================================
2126  * FUNCTION   : getRelatedCamSyncInfo
2127  *
2128  * DESCRIPTION:returns the related cam sync info for this HWI instance
2129  *
2130  * PARAMETERS :none
2131  *
2132  * RETURN     : const pointer to cam_sync_related_sensors_event_info_t
2133  *==========================================================================*/
2134 const cam_sync_related_sensors_event_info_t*
getRelatedCamSyncInfo(void)2135         QCamera2HardwareInterface::getRelatedCamSyncInfo(void)
2136 {
2137     return mParameters.getRelatedCamSyncInfo();
2138 }
2139 
2140 /*===========================================================================
2141  * FUNCTION   : setRelatedCamSyncInfo
2142  *
2143  * DESCRIPTION:sets the related cam sync info for this HWI instance
2144  *
2145  * PARAMETERS :
2146  *   @info  : ptr to related cam info parameters
2147  *
2148  * RETURN     : int32_t type of status
2149  *              NO_ERROR  -- success
2150  *              none-zero failure code
2151  *==========================================================================*/
setRelatedCamSyncInfo(cam_sync_related_sensors_event_info_t * info)2152 int32_t QCamera2HardwareInterface::setRelatedCamSyncInfo(
2153         cam_sync_related_sensors_event_info_t* info)
2154 {
2155     if(info) {
2156         return mParameters.setRelatedCamSyncInfo(info);
2157     } else {
2158         return BAD_TYPE;
2159     }
2160 }
2161 
2162 /*===========================================================================
2163  * FUNCTION   : getMpoComposition
2164  *
2165  * DESCRIPTION:function to retrieve whether Mpo composition should be enabled
2166  *                    or not
2167  *
2168  * PARAMETERS :none
2169  *
2170  * RETURN     : bool indicates whether mpo composition is enabled or not
2171  *==========================================================================*/
getMpoComposition(void)2172 bool QCamera2HardwareInterface::getMpoComposition(void)
2173 {
2174     LOGH("MpoComposition:%d ", m_bMpoEnabled);
2175     return m_bMpoEnabled;
2176 }
2177 
2178 /*===========================================================================
2179  * FUNCTION   : setMpoComposition
2180  *
2181  * DESCRIPTION:set if Mpo composition should be enabled for this HWI instance
2182  *
2183  * PARAMETERS :
2184  *   @enable  : indicates whether Mpo composition enabled or not
2185  *
2186  * RETURN     : int32_t type of status
2187  *              NO_ERROR  -- success
2188  *              none-zero failure code
2189  *==========================================================================*/
setMpoComposition(bool enable)2190 int32_t QCamera2HardwareInterface::setMpoComposition(bool enable)
2191 {
2192     // By default set Mpo composition to disable
2193     m_bMpoEnabled = false;
2194 
2195     // Enable Mpo composition only if
2196     // 1) frame sync is ON between two cameras and
2197     // 2) any advanced features are not enabled (AOST features) and
2198     // 3) not in recording mode (for liveshot case)
2199     // 4) flash is not needed
2200     if ((getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) &&
2201             !mParameters.isAdvCamFeaturesEnabled() &&
2202             !mParameters.getRecordingHintValue() &&
2203             !mFlashNeeded &&
2204             !isLongshotEnabled()) {
2205         m_bMpoEnabled = enable;
2206         LOGH("MpoComposition:%d ", m_bMpoEnabled);
2207         return NO_ERROR;
2208     } else {
2209         return BAD_TYPE;
2210     }
2211 }
2212 
2213 /*===========================================================================
2214  * FUNCTION   : getRecordingHintValue
2215  *
2216  * DESCRIPTION:function to retrieve recording hint value
2217  *
2218  * PARAMETERS :none
2219  *
2220  * RETURN     : bool indicates whether recording hint is enabled or not
2221  *==========================================================================*/
getRecordingHintValue(void)2222 bool QCamera2HardwareInterface::getRecordingHintValue(void)
2223 {
2224     return mParameters.getRecordingHintValue();
2225 }
2226 
2227 /*===========================================================================
2228  * FUNCTION   : setRecordingHintValue
2229  *
2230  * DESCRIPTION:set recording hint value
2231  *
2232  * PARAMETERS :
2233  *   @enable  : video hint value
2234  *
2235  * RETURN     : int32_t type of status
2236  *              NO_ERROR  -- success
2237  *              none-zero failure code
2238  *==========================================================================*/
setRecordingHintValue(int32_t value)2239 int32_t QCamera2HardwareInterface::setRecordingHintValue(int32_t value)
2240 {
2241     return mParameters.updateRecordingHintValue(value);
2242 }
2243 
2244 /*===========================================================================
2245  * FUNCTION   : closeCamera
2246  *
2247  * DESCRIPTION: close camera
2248  *
2249  * PARAMETERS : none
2250  *
2251  * RETURN     : int32_t type of status
2252  *              NO_ERROR  -- success
2253  *              none-zero failure code
2254  *==========================================================================*/
closeCamera()2255 int QCamera2HardwareInterface::closeCamera()
2256 {
2257     int rc = NO_ERROR;
2258     int i;
2259     char value[PROPERTY_VALUE_MAX];
2260     LOGI("E");
2261     if (!mCameraOpened) {
2262         return NO_ERROR;
2263     }
2264     LOGI("[KPI Perf]: E PROFILE_CLOSE_CAMERA camera id %d",
2265              mCameraId);
2266 
2267     // set open flag to false
2268     mCameraOpened = false;
2269 
2270     // Reset Stream config info
2271     mParameters.setStreamConfigure(false, false, true);
2272 
2273     // deinit Parameters
2274     mParameters.deinit();
2275 
2276     // exit notifier
2277     m_cbNotifier.exit();
2278 
2279     // stop and deinit postprocessor
2280     waitDeferredWork(mReprocJob);
2281     // Close the JPEG session
2282     waitDeferredWork(mJpegJob);
2283     m_postprocessor.stop();
2284     deinitJpegHandle();
2285     m_postprocessor.deinit();
2286     mInitPProcJob = 0; // reset job id, so pproc can be reinited later
2287 
2288     m_thermalAdapter.deinit();
2289 
2290     // delete all channels if not already deleted
2291     for (i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
2292         if (m_channels[i] != NULL) {
2293             m_channels[i]->stop();
2294             delete m_channels[i];
2295             m_channels[i] = NULL;
2296         }
2297     }
2298 
2299     //free all pending api results here
2300     if(m_apiResultList != NULL) {
2301         api_result_list *apiResultList = m_apiResultList;
2302         api_result_list *apiResultListNext;
2303         while (apiResultList != NULL) {
2304             apiResultListNext = apiResultList->next;
2305             free(apiResultList);
2306             apiResultList = apiResultListNext;
2307         }
2308     }
2309 
2310     rc = mCameraHandle->ops->close_camera(mCameraHandle->camera_handle);
2311     mCameraHandle = NULL;
2312 
2313     //Notify display HAL that there is no active camera session
2314     //but avoid calling the same during bootup. Refer to openCamera
2315     //for more details.
2316     property_get("service.bootanim.exit", value, "0");
2317     if (atoi(value) == 1) {
2318         pthread_mutex_lock(&gCamLock);
2319         if (--gNumCameraSessions == 0) {
2320             setCameraLaunchStatus(false);
2321         }
2322         pthread_mutex_unlock(&gCamLock);
2323     }
2324 
2325     if (mExifParams.debug_params) {
2326         free(mExifParams.debug_params);
2327         mExifParams.debug_params = NULL;
2328     }
2329 
2330     if (QCameraFlash::getInstance().releaseFlashFromCamera(mCameraId) != 0) {
2331         LOGD("Failed to release flash for camera id: %d",
2332                 mCameraId);
2333     }
2334 
2335     LOGI("[KPI Perf]: X PROFILE_CLOSE_CAMERA camera id %d, rc: %d",
2336          mCameraId, rc);
2337 
2338     return rc;
2339 }
2340 
2341 #define DATA_PTR(MEM_OBJ,INDEX) MEM_OBJ->getPtr( INDEX )
2342 
2343 
2344 /*===========================================================================
2345  * FUNCTION   : getCapabilities
2346  *
2347  * DESCRIPTION: query camera capability from back-end
2348  *
2349  * PARAMETERS :
2350  *   @ops        : mm-interface ops structure
2351  *   @cam_handle  : camera handle for which we need capability
2352  *
2353  * RETURN     : ptr type of capability structure
2354  *              capability for success
2355  *              NULL for failure
2356  *==========================================================================*/
getCapabilities(mm_camera_ops_t * ops,uint32_t cam_handle)2357 cam_capability_t *QCamera2HardwareInterface::getCapabilities(mm_camera_ops_t *ops,
2358         uint32_t cam_handle)
2359 {
2360     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_GET_CAP);
2361     int rc = NO_ERROR;
2362     QCameraHeapMemory *capabilityHeap = NULL;
2363     cam_capability_t *cap_ptr = NULL;
2364 
2365     if (ops == NULL) {
2366         LOGE("Invalid arguments");
2367         return NULL;
2368     }
2369 
2370     capabilityHeap = new QCameraHeapMemory(1);
2371     if (capabilityHeap == NULL) {
2372         LOGE("creation of capabilityHeap failed");
2373         return NULL;
2374     }
2375 
2376     /* Allocate memory for capability buffer */
2377     rc = capabilityHeap->allocate(1, sizeof(cam_capability_t), NON_SECURE);
2378     if(rc != OK) {
2379         LOGE("No memory for capability");
2380         goto allocate_failed;
2381     }
2382 
2383     /* Map memory for capability buffer */
2384     memset(DATA_PTR(capabilityHeap,0), 0, sizeof(cam_capability_t));
2385 
2386     cam_buf_map_type_list bufMapList;
2387     rc = QCameraBufferMaps::makeSingletonBufMapList(
2388             CAM_MAPPING_BUF_TYPE_CAPABILITY,
2389             0 /*stream id*/, 0 /*buffer index*/, -1 /*plane index*/,
2390             0 /*cookie*/, capabilityHeap->getFd(0), sizeof(cam_capability_t),
2391             bufMapList, capabilityHeap->getPtr(0));
2392 
2393     if (rc == NO_ERROR) {
2394         rc = ops->map_bufs(cam_handle,
2395                 &bufMapList);
2396     }
2397     if(rc < 0) {
2398         LOGE("failed to map capability buffer");
2399         goto map_failed;
2400     }
2401 
2402     /* Query Capability */
2403     rc = ops->query_capability(cam_handle);
2404     if(rc < 0) {
2405         LOGE("failed to query capability");
2406         rc = FAILED_TRANSACTION;
2407         goto query_failed;
2408     }
2409 
2410     cap_ptr = (cam_capability_t *)malloc(sizeof(cam_capability_t));
2411     if (cap_ptr == NULL) {
2412         LOGE("out of memory");
2413         rc = NO_MEMORY;
2414         goto query_failed;
2415     }
2416 
2417     memset(cap_ptr, 0, sizeof(cam_capability_t));
2418     memcpy(cap_ptr, DATA_PTR(capabilityHeap, 0), sizeof(cam_capability_t));
2419 
2420     int index;
2421     for (index = 0; index < CAM_ANALYSIS_INFO_MAX; index++) {
2422         cam_analysis_info_t *p_analysis_info = &cap_ptr->analysis_info[index];
2423         p_analysis_info->analysis_padding_info.offset_info.offset_x = 0;
2424         p_analysis_info->analysis_padding_info.offset_info.offset_y = 0;
2425     }
2426 
2427 query_failed:
2428     ops->unmap_buf(cam_handle, CAM_MAPPING_BUF_TYPE_CAPABILITY);
2429 map_failed:
2430     capabilityHeap->deallocate();
2431 allocate_failed:
2432     delete capabilityHeap;
2433 
2434     if (rc != NO_ERROR) {
2435         return NULL;
2436     } else {
2437         return cap_ptr;
2438     }
2439 }
2440 
2441 /*===========================================================================
2442  * FUNCTION   : initCapabilities
2443  *
2444  * DESCRIPTION: initialize camera capabilities in static data struct
2445  *
2446  * PARAMETERS :
2447  *   @cameraId  : camera Id
2448  *
2449  * RETURN     : int32_t type of status
2450  *              NO_ERROR  -- success
2451  *              none-zero failure code
2452  *==========================================================================*/
initCapabilities(uint32_t cameraId,mm_camera_vtbl_t * cameraHandle)2453 int QCamera2HardwareInterface::initCapabilities(uint32_t cameraId,
2454         mm_camera_vtbl_t *cameraHandle)
2455 {
2456     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_INIT_CAP);
2457     int rc = 0;
2458     uint32_t handle = 0;
2459 
2460     rc = camera_open((uint8_t)cameraId, &cameraHandle);
2461     if (rc) {
2462         LOGE("camera_open failed. rc = %d", rc);
2463         goto open_failed;
2464     }
2465     if (!cameraHandle) {
2466         LOGE("camera_open failed. cameraHandle = %p", cameraHandle);
2467         goto open_failed;
2468     }
2469 
2470     handle = get_main_camera_handle(cameraHandle->camera_handle);
2471     gCamCapability[cameraId] = getCapabilities(cameraHandle->ops, handle);
2472     if (gCamCapability[cameraId] == NULL) {
2473         rc = FAILED_TRANSACTION;
2474         goto failed_op;
2475     }
2476 
2477     gCamCapability[cameraId]->camera_index = cameraId;
2478     if (is_dual_camera_by_idx(cameraId)) {
2479         handle = get_aux_camera_handle(cameraHandle->camera_handle);
2480         gCamCapability[cameraId]->aux_cam_cap =
2481                 getCapabilities(cameraHandle->ops, handle);
2482         if (gCamCapability[cameraId]->aux_cam_cap == NULL) {
2483             rc = FAILED_TRANSACTION;
2484             free(gCamCapability[cameraId]);
2485             goto failed_op;
2486         }
2487 
2488         // Copy the main camera capability to main_cam_cap struct
2489         gCamCapability[cameraId]->main_cam_cap =
2490                 (cam_capability_t *)malloc(sizeof(cam_capability_t));
2491         if (gCamCapability[cameraId]->main_cam_cap == NULL) {
2492             LOGE("out of memory");
2493             rc = NO_MEMORY;
2494             goto failed_op;
2495         }
2496         memcpy(gCamCapability[cameraId]->main_cam_cap, gCamCapability[cameraId],
2497                 sizeof(cam_capability_t));
2498     }
2499 failed_op:
2500     cameraHandle->ops->close_camera(cameraHandle->camera_handle);
2501     cameraHandle = NULL;
2502 open_failed:
2503     return rc;
2504 }
2505 
2506 /*===========================================================================
2507  * FUNCTION   : getCapabilities
2508  *
2509  * DESCRIPTION: query camera capabilities
2510  *
2511  * PARAMETERS :
2512  *   @cameraId  : camera Id
2513  *   @info      : camera info struct to be filled in with camera capabilities
2514  *
2515  * RETURN     : int type of status
2516  *              NO_ERROR  -- success
2517  *              none-zero failure code
2518  *==========================================================================*/
getCapabilities(uint32_t cameraId,struct camera_info * info,cam_sync_type_t * p_cam_type)2519 int QCamera2HardwareInterface::getCapabilities(uint32_t cameraId,
2520         struct camera_info *info, cam_sync_type_t *p_cam_type)
2521 {
2522     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_GET_CAP);
2523     int rc = NO_ERROR;
2524     struct  camera_info *p_info = NULL;
2525     pthread_mutex_lock(&gCamLock);
2526     p_info = get_cam_info(cameraId, p_cam_type);
2527     p_info->device_version = CAMERA_DEVICE_API_VERSION_1_0;
2528     p_info->static_camera_characteristics = NULL;
2529     memcpy(info, p_info, sizeof (struct camera_info));
2530     pthread_mutex_unlock(&gCamLock);
2531     return rc;
2532 }
2533 
2534 /*===========================================================================
2535  * FUNCTION   : getCamHalCapabilities
2536  *
2537  * DESCRIPTION: get the HAL capabilities structure
2538  *
2539  * PARAMETERS :
2540  *   @cameraId  : camera Id
2541  *
2542  * RETURN     : capability structure of respective camera
2543  *
2544  *==========================================================================*/
getCamHalCapabilities()2545 cam_capability_t* QCamera2HardwareInterface::getCamHalCapabilities()
2546 {
2547     return gCamCapability[mCameraId];
2548 }
2549 
2550 /*===========================================================================
2551  * FUNCTION   : getBufNumForAux
2552  *
2553  * DESCRIPTION: return number of stream buffers needed for aux camera given stream type
2554  *
2555  * PARAMETERS :
2556  *   @stream_type  : type of stream
2557  *
2558  * RETURN     : number of buffers needed
2559  * NOTE     :  Based on the use cases and auxillary camera type,
2560                     we can decide buffer count
2561  *==========================================================================*/
getBufNumForAux(cam_stream_type_t stream_type)2562 uint8_t QCamera2HardwareInterface::getBufNumForAux(cam_stream_type_t stream_type)
2563 {
2564     if (!isDualCamera()) {
2565         return 0;
2566     }
2567 
2568     uint8_t bufferCnt = 1;
2569     switch (stream_type) {
2570     case CAM_STREAM_TYPE_PREVIEW:
2571     case CAM_STREAM_TYPE_VIDEO:
2572     case CAM_STREAM_TYPE_SNAPSHOT:
2573     case CAM_STREAM_TYPE_METADATA:
2574     case CAM_STREAM_TYPE_CALLBACK:
2575     case CAM_STREAM_TYPE_ANALYSIS:
2576     case CAM_STREAM_TYPE_POSTVIEW:
2577     case CAM_STREAM_TYPE_RAW:
2578     case CAM_STREAM_TYPE_OFFLINE_PROC:
2579     case CAM_STREAM_TYPE_DEFAULT:
2580     case CAM_STREAM_TYPE_MAX:
2581         //For wide & tele, we use same buffer count premary and aux streams.
2582         bufferCnt = getBufNumRequired(stream_type);
2583         break;
2584     default:
2585         break;
2586     }
2587     LOGH("Buffer Cnt for Aux Camera : %d", bufferCnt);
2588     return bufferCnt;
2589 }
2590 
2591 /*===========================================================================
2592  * FUNCTION   : getBufNumRequired
2593  *
2594  * DESCRIPTION: return number of stream buffers needed for given stream type
2595  *
2596  * PARAMETERS :
2597  *   @stream_type  : type of stream
2598  *
2599  * RETURN     : number of buffers needed
2600  *==========================================================================*/
getBufNumRequired(cam_stream_type_t stream_type)2601 uint8_t QCamera2HardwareInterface::getBufNumRequired(cam_stream_type_t stream_type)
2602 {
2603     int bufferCnt = 0;
2604     int minCaptureBuffers = mParameters.getNumOfSnapshots();
2605     char value[PROPERTY_VALUE_MAX];
2606     bool raw_yuv = false;
2607     int persist_cnt = 0;
2608     int minPrevFps, maxPrevFps;
2609 
2610     int zslQBuffers = mParameters.getZSLQueueDepth();
2611 
2612     int minCircularBufNum = mParameters.getMaxUnmatchedFramesInQueue() +
2613                             CAMERA_MIN_JPEG_ENCODING_BUFFERS;
2614 
2615     int maxStreamBuf = minCaptureBuffers + mParameters.getMaxUnmatchedFramesInQueue() +
2616                        mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2617                        mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2618                        mParameters.getNumOfExtraBuffersForImageProc() +
2619                        EXTRA_ZSL_PREVIEW_STREAM_BUF;
2620 
2621     int minUndequeCount = 0;
2622     if (!isNoDisplayMode()) {
2623         if(mPreviewWindow != NULL) {
2624             if (mPreviewWindow->get_min_undequeued_buffer_count(mPreviewWindow,&minUndequeCount)
2625                 != 0) {
2626                 LOGW("get_min_undequeued_buffer_count  failed");
2627                 //TODO: hardcoded because MIN_UNDEQUEUED_BUFFERS not defined
2628                 //minUndequeCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS;
2629                 minUndequeCount = MIN_UNDEQUEUED_BUFFERS;
2630             }
2631         } else {
2632             //preview window might not be set at this point. So, query directly
2633             //from BufferQueue implementation of gralloc buffers.
2634             //minUndequeCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS;
2635             //hardcoded because MIN_UNDEQUEUED_BUFFERS not defined. REVISIT
2636             minUndequeCount = MIN_UNDEQUEUED_BUFFERS;
2637         }
2638         if (minUndequeCount != MIN_UNDEQUEUED_BUFFERS) {
2639             // minUndequeCount from valid preview window != hardcoded MIN_UNDEQUEUED_BUFFERS
2640             // and so change the MACRO as per minUndequeCount
2641             LOGW("WARNING : minUndequeCount(%d) != hardcoded value(%d)",
2642                      minUndequeCount, MIN_UNDEQUEUED_BUFFERS);
2643         }
2644     }
2645 
2646     LOGD("minCaptureBuffers = %d zslQBuffers = %d minCircularBufNum = %d"
2647             "maxStreamBuf = %d minUndequeCount = %d",
2648             minCaptureBuffers, zslQBuffers, minCircularBufNum,
2649             maxStreamBuf, minUndequeCount);
2650     // Get buffer count for the particular stream type
2651     switch (stream_type) {
2652     case CAM_STREAM_TYPE_PREVIEW:
2653         {
2654             if (mParameters.isZSLMode()) {
2655                 // We need to add two extra streming buffers to add
2656                 // flexibility in forming matched super buf in ZSL queue.
2657                 // with number being 'zslQBuffers + minCircularBufNum'
2658                 // we see preview buffers sometimes get dropped at CPP
2659                 // and super buf is not forming in ZSL Q for long time.
2660 
2661                 bufferCnt = zslQBuffers + minCircularBufNum +
2662                         mParameters.getNumOfExtraBuffersForImageProc() +
2663                         mParameters.getNumOfExtraBuffersForPreview() +
2664                         mParameters.getNumOfExtraHDRInBufsIfNeeded();
2665             } else {
2666                 bufferCnt = CAMERA_MIN_STREAMING_BUFFERS +
2667                         mParameters.getMaxUnmatchedFramesInQueue() +
2668                         mParameters.getNumOfExtraBuffersForPreview();
2669             }
2670             // ISP allocates native preview buffers and so reducing same from HAL allocation
2671             if (bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS )
2672                 bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS;
2673 
2674             // Extra ZSL preview frames are not needed for HFR case.
2675             // Thumbnail will not be derived from preview for HFR live snapshot case.
2676             if ((mParameters.getRecordingHintValue() == true)
2677                     && (!mParameters.isHfrMode())) {
2678                 bufferCnt += EXTRA_ZSL_PREVIEW_STREAM_BUF;
2679             }
2680             //Adding Extra preview buffers for 60FPS usecase.
2681             mParameters.getPreviewFpsRange(&minPrevFps, &maxPrevFps);
2682             if (maxPrevFps > CAMERA_DEFAULT_FPS) {
2683                 bufferCnt += CAMERA_MIN_DISPLAY_BUFFERS;
2684             }
2685 
2686             // Add the display minUndequeCount count on top of camera requirement
2687             bufferCnt += minUndequeCount;
2688 
2689             property_get("persist.camera.preview_yuv", value, "0");
2690             persist_cnt = atoi(value);
2691             if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM)
2692                     && (bufferCnt < persist_cnt)) {
2693                 bufferCnt = persist_cnt;
2694             }
2695         }
2696         break;
2697     case CAM_STREAM_TYPE_POSTVIEW:
2698         {
2699             bufferCnt = minCaptureBuffers +
2700                         mParameters.getMaxUnmatchedFramesInQueue() +
2701                         mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2702                         mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2703                         mParameters.getNumOfExtraBuffersForImageProc();
2704 
2705             if (bufferCnt > maxStreamBuf) {
2706                 bufferCnt = maxStreamBuf;
2707             }
2708             bufferCnt += minUndequeCount;
2709         }
2710         break;
2711     case CAM_STREAM_TYPE_SNAPSHOT:
2712         {
2713             if (mParameters.isZSLMode() || mLongshotEnabled) {
2714                 if ((minCaptureBuffers == 1 || mParameters.isUbiRefocus()) &&
2715                         !mLongshotEnabled) {
2716                     // Single ZSL snapshot case
2717                     bufferCnt = zslQBuffers + CAMERA_MIN_STREAMING_BUFFERS +
2718                             mParameters.getNumOfExtraBuffersForImageProc();
2719                 }
2720                 else {
2721                     // ZSL Burst or Longshot case
2722                     bufferCnt = zslQBuffers + minCircularBufNum +
2723                             mParameters.getNumOfExtraBuffersForImageProc();
2724                 }
2725                 if (getSensorType() == CAM_SENSOR_YUV && bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS) {
2726                     //ISP allocates native buffers in YUV case
2727                     bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS;
2728                 }
2729             } else {
2730                 bufferCnt = minCaptureBuffers +
2731                             mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2732                             mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2733                             mParameters.getNumOfExtraBuffersForImageProc();
2734 
2735                 if (bufferCnt > maxStreamBuf) {
2736                     bufferCnt = maxStreamBuf;
2737                 }
2738             }
2739         }
2740         break;
2741     case CAM_STREAM_TYPE_RAW:
2742         property_get("persist.camera.raw_yuv", value, "0");
2743         raw_yuv = atoi(value) > 0 ? true : false;
2744 
2745         if (isRdiMode() || raw_yuv) {
2746             bufferCnt = zslQBuffers + minCircularBufNum;
2747         } else if (mParameters.isZSLMode()) {
2748             bufferCnt = zslQBuffers + minCircularBufNum;
2749             if (getSensorType() == CAM_SENSOR_YUV && bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS) {
2750                 //ISP allocates native buffers in YUV case
2751                 bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS;
2752             }
2753 
2754         } else {
2755             bufferCnt = minCaptureBuffers +
2756                         mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2757                         mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2758                         mParameters.getNumOfExtraBuffersForImageProc();
2759 
2760             if (bufferCnt > maxStreamBuf) {
2761                 bufferCnt = maxStreamBuf;
2762             }
2763         }
2764 
2765         property_get("persist.camera.preview_raw", value, "0");
2766         persist_cnt = atoi(value);
2767         if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM)
2768                 && (bufferCnt < persist_cnt)) {
2769             bufferCnt = persist_cnt;
2770         }
2771         property_get("persist.camera.video_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 
2778         break;
2779     case CAM_STREAM_TYPE_VIDEO:
2780         {
2781             if (mParameters.getBufBatchCount()) {
2782                 //Video Buffer in case of HFR or camera batching..
2783                 bufferCnt = CAMERA_MIN_CAMERA_BATCH_BUFFERS;
2784             } else if (mParameters.getVideoBatchSize()) {
2785                 //Video Buffer count only for HAL to HAL batching.
2786                 bufferCnt = (CAMERA_MIN_VIDEO_BATCH_BUFFERS
2787                         * mParameters.getVideoBatchSize());
2788                 if (bufferCnt < CAMERA_MIN_VIDEO_BUFFERS) {
2789                     bufferCnt = CAMERA_MIN_VIDEO_BUFFERS;
2790                 }
2791             } else {
2792                 // No batching enabled.
2793                 bufferCnt = CAMERA_MIN_VIDEO_BUFFERS;
2794             }
2795 
2796             bufferCnt += mParameters.getNumOfExtraBuffersForVideo();
2797             //if its 4K encoding usecase, then add extra buffer
2798             cam_dimension_t dim;
2799             mParameters.getStreamDimension(CAM_STREAM_TYPE_VIDEO, dim);
2800             if (is4k2kResolution(&dim)) {
2801                  //get additional buffer count
2802                  property_get("vidc.enc.dcvs.extra-buff-count", value, "0");
2803                  bufferCnt += atoi(value);
2804             }
2805         }
2806         break;
2807     case CAM_STREAM_TYPE_METADATA:
2808         {
2809             if (mParameters.isZSLMode()) {
2810                 // MetaData buffers should be >= (Preview buffers-minUndequeCount)
2811                 bufferCnt = zslQBuffers + minCircularBufNum +
2812                             mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2813                             mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2814                             mParameters.getNumOfExtraBuffersForImageProc() +
2815                             EXTRA_ZSL_PREVIEW_STREAM_BUF;
2816             } else {
2817                 bufferCnt = minCaptureBuffers +
2818                             mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2819                             mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2820                             mParameters.getMaxUnmatchedFramesInQueue() +
2821                             CAMERA_MIN_STREAMING_BUFFERS +
2822                             mParameters.getNumOfExtraBuffersForImageProc();
2823 
2824                 if (bufferCnt > zslQBuffers + minCircularBufNum) {
2825                     bufferCnt = zslQBuffers + minCircularBufNum;
2826                 }
2827             }
2828             if (CAMERA_MIN_METADATA_BUFFERS > bufferCnt) {
2829                 bufferCnt = CAMERA_MIN_METADATA_BUFFERS;
2830             }
2831         }
2832         break;
2833     case CAM_STREAM_TYPE_OFFLINE_PROC:
2834         {
2835             bufferCnt = minCaptureBuffers;
2836             // One of the ubifocus buffers is miscellaneous buffer
2837             if (mParameters.isUbiRefocus()) {
2838                 bufferCnt -= 1;
2839             }
2840             if (mLongshotEnabled) {
2841                 bufferCnt = mParameters.getLongshotStages();
2842             }
2843         }
2844         break;
2845     case CAM_STREAM_TYPE_CALLBACK:
2846         bufferCnt = CAMERA_MIN_CALLBACK_BUFFERS;
2847         break;
2848     case CAM_STREAM_TYPE_ANALYSIS:
2849     case CAM_STREAM_TYPE_DEFAULT:
2850     case CAM_STREAM_TYPE_MAX:
2851     default:
2852         bufferCnt = 0;
2853         break;
2854     }
2855 
2856     LOGH("Buffer count = %d for stream type = %d", bufferCnt, stream_type);
2857     if (CAM_MAX_NUM_BUFS_PER_STREAM < bufferCnt) {
2858         LOGW("Buffer count %d for stream type %d exceeds limit %d",
2859                  bufferCnt, stream_type, CAM_MAX_NUM_BUFS_PER_STREAM);
2860         return CAM_MAX_NUM_BUFS_PER_STREAM;
2861     }
2862 
2863     return (uint8_t)bufferCnt;
2864 }
2865 
2866 /*===========================================================================
2867  * FUNCTION   : getStreamRefCount
2868  *
2869  * DESCRIPTION: return number of instance of stream of stream type
2870  *
2871  * PARAMETERS :
2872  *   @stream_type  : type of stream
2873  *
2874  * RETURN     : number of stream instances
2875  * NOTE      :  Based on the use cases and auxillary camera type,
2876                      we can decide stream reference count.
2877                      For example in wide and tele use case, we duplicate all stream
2878                      streams from premary to auxillary.
2879  *==========================================================================*/
getStreamRefCount(cam_stream_type_t stream_type)2880 uint8_t QCamera2HardwareInterface::getStreamRefCount(cam_stream_type_t stream_type)
2881 {
2882     uint8_t ref_cnt = 1;
2883     switch (stream_type) {
2884     case CAM_STREAM_TYPE_PREVIEW:
2885     case CAM_STREAM_TYPE_SNAPSHOT:
2886     case CAM_STREAM_TYPE_VIDEO:
2887     case CAM_STREAM_TYPE_METADATA:
2888     case CAM_STREAM_TYPE_ANALYSIS:
2889     case CAM_STREAM_TYPE_CALLBACK:
2890         if (isDualCamera()) {
2891             ref_cnt++;
2892         }
2893         break;
2894     case CAM_STREAM_TYPE_POSTVIEW:
2895     case CAM_STREAM_TYPE_RAW:
2896     case CAM_STREAM_TYPE_OFFLINE_PROC:
2897     case CAM_STREAM_TYPE_DEFAULT:
2898     case CAM_STREAM_TYPE_MAX:
2899     default:
2900         break;
2901     }
2902     return ref_cnt;
2903 }
2904 
2905 /*===========================================================================
2906  * FUNCTION   : getCamHandleForChannel
2907  *
2908  * DESCRIPTION: return actual camera handle based on use case
2909  *
2910  * PARAMETERS :
2911  *   @ch_type  : type of channel
2912  *
2913  * RETURN     : uint32_t type camera handle
2914  * NOTE :  Based on the use cases and auxillary camera type, we can decide cam handle for channel.
2915                  Incase, we want to avoid any channel for auxillary camera, we can decide here
2916  *==========================================================================*/
getCamHandleForChannel(qcamera_ch_type_enum_t ch_type)2917 uint32_t QCamera2HardwareInterface::getCamHandleForChannel(qcamera_ch_type_enum_t ch_type)
2918 {
2919     uint32_t handle = 0;
2920     if (!isDualCamera()) {
2921         return mCameraHandle->camera_handle;
2922     }
2923 
2924     /*Based on the use case, decide camera handle for channel*/
2925     switch (ch_type) {
2926     case QCAMERA_CH_TYPE_ZSL:
2927     case QCAMERA_CH_TYPE_CAPTURE:
2928     case QCAMERA_CH_TYPE_PREVIEW:
2929     case QCAMERA_CH_TYPE_VIDEO:
2930     case QCAMERA_CH_TYPE_SNAPSHOT:
2931     case QCAMERA_CH_TYPE_RAW:
2932     case QCAMERA_CH_TYPE_METADATA:
2933     case QCAMERA_CH_TYPE_ANALYSIS:
2934     case QCAMERA_CH_TYPE_CALLBACK:
2935     case QCAMERA_CH_TYPE_MAX:
2936     default:
2937         handle = mCameraHandle->camera_handle;
2938         break;
2939     case QCAMERA_CH_TYPE_REPROCESSING:
2940         handle = get_main_camera_handle(mCameraHandle->camera_handle);
2941         break;
2942     }
2943     return handle;
2944 }
2945 
2946 /*===========================================================================
2947  * FUNCTION   : allocateStreamBuf
2948  *
2949  * DESCRIPTION: alocate stream buffers
2950  *
2951  * PARAMETERS :
2952  *   @stream_type  : type of stream
2953  *   @size         : size of buffer
2954  *   @stride       : stride of buffer
2955  *   @scanline     : scanline of buffer
2956  *   @bufferCnt    : [IN/OUT] minimum num of buffers to be allocated.
2957  *                   could be modified during allocation if more buffers needed
2958  *
2959  * RETURN     : ptr to a memory obj that holds stream buffers.
2960  *              NULL if failed
2961  *==========================================================================*/
allocateStreamBuf(cam_stream_type_t stream_type,size_t size,int stride,int scanline,uint8_t & bufferCnt)2962 QCameraMemory *QCamera2HardwareInterface::allocateStreamBuf(
2963         cam_stream_type_t stream_type, size_t size, int stride, int scanline,
2964         uint8_t &bufferCnt)
2965 {
2966     int rc = NO_ERROR;
2967     QCameraMemory *mem = NULL;
2968     bool bCachedMem = QCAMERA_ION_USE_CACHE;
2969     bool bPoolMem = false;
2970     char value[PROPERTY_VALUE_MAX];
2971     property_get("persist.camera.mem.usepool", value, "1");
2972     if (atoi(value) == 1) {
2973         bPoolMem = true;
2974     }
2975 
2976     // Allocate stream buffer memory object
2977     switch (stream_type) {
2978     case CAM_STREAM_TYPE_PREVIEW:
2979         {
2980             if (isNoDisplayMode()) {
2981                 mem = new QCameraStreamMemory(mGetMemory,
2982                         bCachedMem,
2983                         (bPoolMem) ? &m_memoryPool : NULL,
2984                         stream_type);
2985             } else {
2986                 cam_dimension_t dim;
2987                 int minFPS, maxFPS;
2988                 QCameraGrallocMemory *grallocMemory =
2989                     new QCameraGrallocMemory(mGetMemory);
2990 
2991                 mParameters.getStreamDimension(stream_type, dim);
2992                 /* we are interested only in maxfps here */
2993                 mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
2994                 int usage = 0;
2995                 if(mParameters.isUBWCEnabled()) {
2996                     cam_format_t fmt;
2997                     mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW,fmt);
2998                     if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
2999                         usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC ;
3000                     }
3001                 }
3002                 if (grallocMemory) {
3003                     grallocMemory->setMappable(
3004                             CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS);
3005                     grallocMemory->setWindowInfo(mPreviewWindow,
3006                             dim.width,dim.height, stride, scanline,
3007                             mParameters.getPreviewHalPixelFormat(),
3008                             maxFPS, usage);
3009                     pthread_mutex_lock(&mGrallocLock);
3010                     if (bufferCnt > CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS) {
3011                         mEnqueuedBuffers = (bufferCnt -
3012                                 CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS);
3013                     } else {
3014                         mEnqueuedBuffers = 0;
3015                     }
3016                     pthread_mutex_unlock(&mGrallocLock);
3017                 }
3018                 mem = grallocMemory;
3019             }
3020         }
3021         break;
3022     case CAM_STREAM_TYPE_POSTVIEW:
3023         {
3024             if (isNoDisplayMode() || isPreviewRestartEnabled()) {
3025                 mem = new QCameraStreamMemory(mGetMemory, bCachedMem);
3026             } else {
3027                 cam_dimension_t dim;
3028                 int minFPS, maxFPS;
3029                 QCameraGrallocMemory *grallocMemory =
3030                         new QCameraGrallocMemory(mGetMemory);
3031 
3032                 mParameters.getStreamDimension(stream_type, dim);
3033                 /* we are interested only in maxfps here */
3034                 mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
3035                 if (grallocMemory) {
3036                     grallocMemory->setWindowInfo(mPreviewWindow, dim.width,
3037                             dim.height, stride, scanline,
3038                             mParameters.getPreviewHalPixelFormat(), maxFPS);
3039                 }
3040                 mem = grallocMemory;
3041             }
3042         }
3043         break;
3044     case CAM_STREAM_TYPE_ANALYSIS:
3045     case CAM_STREAM_TYPE_SNAPSHOT:
3046     case CAM_STREAM_TYPE_RAW:
3047     case CAM_STREAM_TYPE_OFFLINE_PROC:
3048         mem = new QCameraStreamMemory(mGetMemory,
3049                 bCachedMem,
3050                 (bPoolMem) ? &m_memoryPool : NULL,
3051                 stream_type);
3052         break;
3053     case CAM_STREAM_TYPE_METADATA:
3054         {
3055             if (mMetadataMem == NULL) {
3056                 mem = new QCameraMetadataStreamMemory(QCAMERA_ION_USE_CACHE);
3057             } else {
3058                 mem = mMetadataMem;
3059                 mMetadataMem = NULL;
3060 
3061                 int32_t numAdditionalBuffers = bufferCnt - mem->getCnt();
3062                 if (numAdditionalBuffers > 0) {
3063                     rc = mem->allocateMore(numAdditionalBuffers, size);
3064                     if (rc != NO_ERROR) {
3065                         LOGE("Failed to allocate additional buffers, "
3066                                 "but attempting to proceed.");
3067                     }
3068                 }
3069                 bufferCnt = mem->getCnt();
3070                 // The memory is already allocated  and initialized, so
3071                 // simply return here.
3072                 return mem;
3073             }
3074         }
3075         break;
3076     case CAM_STREAM_TYPE_VIDEO:
3077         {
3078             //Use uncached allocation by default
3079             if (mParameters.isVideoBuffersCached() || mParameters.isSeeMoreEnabled() ||
3080                     mParameters.isHighQualityNoiseReductionMode()) {
3081                 bCachedMem = QCAMERA_ION_USE_CACHE;
3082             }
3083             else {
3084                 bCachedMem = QCAMERA_ION_USE_NOCACHE;
3085             }
3086 
3087             QCameraVideoMemory *videoMemory = NULL;
3088             if (mParameters.getVideoBatchSize()) {
3089                 videoMemory = new QCameraVideoMemory(
3090                         mGetMemory, FALSE, QCAMERA_MEM_TYPE_BATCH);
3091                 if (videoMemory == NULL) {
3092                     LOGE("Out of memory for video batching obj");
3093                     return NULL;
3094                 }
3095                 /*
3096                 *   numFDs = BATCH size
3097                 *  numInts = 5  // OFFSET, SIZE, USAGE, TIMESTAMP, FORMAT
3098                 */
3099                 rc = videoMemory->allocateMeta(
3100                         CAMERA_MIN_VIDEO_BATCH_BUFFERS,
3101                         mParameters.getVideoBatchSize(),
3102                         VIDEO_METADATA_NUM_INTS);
3103                 if (rc < 0) {
3104                     delete videoMemory;
3105                     return NULL;
3106                 }
3107             } else {
3108                 videoMemory =
3109                         new QCameraVideoMemory(mGetMemory, bCachedMem);
3110                 if (videoMemory == NULL) {
3111                     LOGE("Out of memory for video obj");
3112                     return NULL;
3113                 }
3114             }
3115 
3116             int usage = 0;
3117             cam_format_t fmt;
3118             mParameters.getStreamFormat(CAM_STREAM_TYPE_VIDEO,fmt);
3119             if (mParameters.isUBWCEnabled() && (fmt == CAM_FORMAT_YUV_420_NV12_UBWC)) {
3120                 usage = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
3121             }
3122             videoMemory->setVideoInfo(usage, fmt);
3123             mem = videoMemory;
3124         }
3125         break;
3126     case CAM_STREAM_TYPE_CALLBACK:
3127         mem = new QCameraStreamMemory(mGetMemory,
3128                 bCachedMem,
3129                 (bPoolMem) ? &m_memoryPool : NULL,
3130                 stream_type);
3131         break;
3132     case CAM_STREAM_TYPE_DEFAULT:
3133     case CAM_STREAM_TYPE_MAX:
3134     default:
3135         break;
3136     }
3137     if (!mem) {
3138         return NULL;
3139     }
3140 
3141     if (bufferCnt > 0) {
3142         if (mParameters.isSecureMode() &&
3143             (stream_type == CAM_STREAM_TYPE_RAW) &&
3144             (mParameters.isRdiMode())) {
3145             LOGD("Allocating %d secure buffers of size %d ", bufferCnt, size);
3146             rc = mem->allocate(bufferCnt, size, SECURE);
3147         } else {
3148             rc = mem->allocate(bufferCnt, size, NON_SECURE);
3149         }
3150         if (rc < 0) {
3151             delete mem;
3152             return NULL;
3153         }
3154         bufferCnt = mem->getCnt();
3155     }
3156     LOGH("rc = %d type = %d count = %d size = %d cache = %d, pool = %d mEnqueuedBuffers = %d",
3157             rc, stream_type, bufferCnt, size, bCachedMem, bPoolMem, mEnqueuedBuffers);
3158     return mem;
3159 }
3160 
3161 /*===========================================================================
3162  * FUNCTION   : allocateMoreStreamBuf
3163  *
3164  * DESCRIPTION: alocate more stream buffers from the memory object
3165  *
3166  * PARAMETERS :
3167  *   @mem_obj      : memory object ptr
3168  *   @size         : size of buffer
3169  *   @bufferCnt    : [IN/OUT] additional number of buffers to be allocated.
3170  *                   output will be the number of total buffers
3171  *
3172  * RETURN     : int32_t type of status
3173  *              NO_ERROR  -- success
3174  *              none-zero failure code
3175  *==========================================================================*/
allocateMoreStreamBuf(QCameraMemory * mem_obj,size_t size,uint8_t & bufferCnt)3176 int32_t QCamera2HardwareInterface::allocateMoreStreamBuf(
3177         QCameraMemory *mem_obj, size_t size, uint8_t &bufferCnt)
3178 {
3179     int rc = NO_ERROR;
3180 
3181     if (bufferCnt > 0) {
3182         rc = mem_obj->allocateMore(bufferCnt, size);
3183         bufferCnt = mem_obj->getCnt();
3184     }
3185     return rc;
3186 }
3187 
3188 /*===========================================================================
3189  * FUNCTION   : allocateMiscBuf
3190  *
3191  * DESCRIPTION: alocate miscellaneous buffer
3192  *
3193  * PARAMETERS :
3194  *   @streamInfo  : stream info
3195  *
3196  * RETURN     : ptr to a memory obj that holds stream info buffer.
3197  *              NULL if failed
3198  *==========================================================================*/
allocateMiscBuf(cam_stream_info_t * streamInfo)3199 QCameraHeapMemory *QCamera2HardwareInterface::allocateMiscBuf(
3200         cam_stream_info_t *streamInfo)
3201 {
3202     int rc = NO_ERROR;
3203     uint8_t bufNum = 0;
3204     size_t bufSize = 0;
3205     QCameraHeapMemory *miscBuf = NULL;
3206     cam_feature_mask_t feature_mask =
3207             streamInfo->reprocess_config.pp_feature_config.feature_mask;
3208 
3209     switch (streamInfo->stream_type) {
3210     case CAM_STREAM_TYPE_OFFLINE_PROC:
3211         if (CAM_QCOM_FEATURE_TRUEPORTRAIT & feature_mask) {
3212             bufNum = 1;
3213             bufSize = mParameters.getTPMaxMetaSize();
3214         } else if (CAM_QCOM_FEATURE_REFOCUS & feature_mask) {
3215             bufNum = 1;
3216             bufSize = mParameters.getRefocusMaxMetaSize();
3217         }
3218         break;
3219     default:
3220         break;
3221     }
3222 
3223     if (bufNum && bufSize) {
3224         miscBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
3225 
3226         if (!miscBuf) {
3227             LOGE("Unable to allocate miscBuf object");
3228             return NULL;
3229         }
3230 
3231         rc = miscBuf->allocate(bufNum, bufSize, NON_SECURE);
3232         if (rc < 0) {
3233             LOGE("Failed to allocate misc buffer memory");
3234             delete miscBuf;
3235             return NULL;
3236         }
3237     }
3238 
3239     return miscBuf;
3240 }
3241 
3242 /*===========================================================================
3243  * FUNCTION   : initStreamInfoBuf
3244  *
3245  * DESCRIPTION: initialize stream info buffer based on stream type
3246  *
3247  * PARAMETERS :
3248  *   @stream_type  : type of stream
3249  *
3250  * RETURN     : ptr to a memory obj that holds stream info buffer.
3251  *              NULL if failed
3252  *==========================================================================*/
initStreamInfoBuf(cam_stream_type_t stream_type,cam_stream_info_t * streamInfo)3253 int QCamera2HardwareInterface::initStreamInfoBuf(cam_stream_type_t stream_type,
3254             cam_stream_info_t *streamInfo)
3255 {
3256     int rc = NO_ERROR;
3257     int32_t dt = 0;
3258     int32_t vc = 0;
3259 
3260     memset(streamInfo, 0, sizeof(cam_stream_info_t));
3261     streamInfo->stream_type = stream_type;
3262     rc = mParameters.getStreamFormat(stream_type, streamInfo->fmt);
3263     rc = mParameters.getStreamDimension(stream_type, streamInfo->dim);
3264     rc = mParameters.getStreamRotation(stream_type, streamInfo->pp_config, streamInfo->dim);
3265     streamInfo->num_bufs = getBufNumRequired(stream_type);
3266     streamInfo->buf_cnt = streamInfo->num_bufs;
3267     streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
3268     streamInfo->is_secure = NON_SECURE;
3269     // Initialize cache ops
3270     if (!m_bOptimizeCacheOps) {
3271         streamInfo->cache_ops = CAM_STREAM_CACHE_OPS_DISABLED;
3272     } else {
3273         streamInfo->cache_ops = CAM_STREAM_CACHE_OPS_HONOUR_FLAGS;
3274     }
3275 
3276     switch (stream_type) {
3277     case CAM_STREAM_TYPE_SNAPSHOT:
3278         if ((mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) ||
3279             mLongshotEnabled) {
3280             streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
3281         } else {
3282             streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
3283             streamInfo->num_of_burst = (uint8_t)
3284                     (mParameters.getNumOfSnapshots()
3285                         + mParameters.getNumOfExtraHDRInBufsIfNeeded()
3286                         - mParameters.getNumOfExtraHDROutBufsIfNeeded()
3287                         + mParameters.getNumOfExtraBuffersForImageProc());
3288         }
3289         break;
3290     case CAM_STREAM_TYPE_RAW: {
3291             char value[PROPERTY_VALUE_MAX];
3292             bool raw_yuv = false;
3293             property_get("persist.camera.raw_yuv", value, "0");
3294             raw_yuv = atoi(value) > 0 ? true : false;
3295             if ((mParameters.isZSLMode()) || (isRdiMode()) || (raw_yuv)) {
3296                 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
3297             } else {
3298                 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
3299                 streamInfo->num_of_burst = mParameters.getNumOfSnapshots();
3300             }
3301             if (mParameters.isSecureMode() && mParameters.isRdiMode()) {
3302                 streamInfo->is_secure = SECURE;
3303             } else {
3304                 streamInfo->is_secure = NON_SECURE;
3305             }
3306         }
3307         if (CAM_FORMAT_META_RAW_10BIT == streamInfo->fmt) {
3308             mParameters.updateDtVc(&dt, &vc);
3309             if (dt)
3310                 streamInfo->dt = dt;
3311             streamInfo->vc = vc;
3312         }
3313 
3314         break;
3315     case CAM_STREAM_TYPE_POSTVIEW:
3316         if (mLongshotEnabled) {
3317             streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
3318         } else {
3319             streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
3320             streamInfo->num_of_burst = (uint8_t)(mParameters.getNumOfSnapshots()
3321                 + mParameters.getNumOfExtraHDRInBufsIfNeeded()
3322                 - mParameters.getNumOfExtraHDROutBufsIfNeeded()
3323                 + mParameters.getNumOfExtraBuffersForImageProc());
3324         }
3325         break;
3326     case CAM_STREAM_TYPE_VIDEO:
3327         streamInfo->dis_enable = mParameters.isDISEnabled();
3328         if (mParameters.getBufBatchCount()) {
3329             //Update stream info structure with batch mode info
3330             streamInfo->streaming_mode = CAM_STREAMING_MODE_BATCH;
3331             streamInfo->user_buf_info.frame_buf_cnt = mParameters.getBufBatchCount();
3332             streamInfo->user_buf_info.size =
3333                     (uint32_t)(sizeof(struct msm_camera_user_buf_cont_t));
3334             cam_fps_range_t pFpsRange;
3335             mParameters.getHfrFps(pFpsRange);
3336             streamInfo->user_buf_info.frameInterval =
3337                     (long)((1000/pFpsRange.video_max_fps) * 1000);
3338             LOGH("Video Batch Count = %d, interval = %d",
3339                     streamInfo->user_buf_info.frame_buf_cnt,
3340                     streamInfo->user_buf_info.frameInterval);
3341         }
3342         if (mParameters.getRecordingHintValue()) {
3343             if(mParameters.isDISEnabled()) {
3344                 streamInfo->is_type = mParameters.getVideoISType();
3345             } else {
3346                 streamInfo->is_type = IS_TYPE_NONE;
3347             }
3348         }
3349         if (mParameters.isSecureMode()) {
3350             streamInfo->is_secure = SECURE;
3351         }
3352         break;
3353     case CAM_STREAM_TYPE_PREVIEW:
3354         if (mParameters.getRecordingHintValue()) {
3355             if(mParameters.isDISEnabled()) {
3356                 streamInfo->is_type = mParameters.getPreviewISType();
3357             } else {
3358                 streamInfo->is_type = IS_TYPE_NONE;
3359             }
3360         }
3361         if (mParameters.isSecureMode()) {
3362             streamInfo->is_secure = SECURE;
3363         }
3364         break;
3365     case CAM_STREAM_TYPE_ANALYSIS:
3366         streamInfo->noFrameExpected = 1;
3367         break;
3368     case CAM_STREAM_TYPE_METADATA:
3369         streamInfo->cache_ops = CAM_STREAM_CACHE_OPS_CLEAR_FLAGS;
3370         break;
3371     default:
3372         break;
3373     }
3374 
3375     // Update feature mask
3376     mParameters.updatePpFeatureMask(stream_type);
3377 
3378     // Get feature mask
3379     mParameters.getStreamPpMask(stream_type, streamInfo->pp_config.feature_mask);
3380 
3381     // Update pp config
3382     if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_FLIP) {
3383         int flipMode = mParameters.getFlipMode(stream_type);
3384         if (flipMode > 0) {
3385             streamInfo->pp_config.flip = (uint32_t)flipMode;
3386         }
3387     }
3388     if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_SHARPNESS) {
3389         streamInfo->pp_config.sharpness = mParameters.getSharpness();
3390     }
3391     if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_EFFECT) {
3392         streamInfo->pp_config.effect = mParameters.getEffectValue();
3393     }
3394 
3395     if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_DENOISE2D) {
3396         streamInfo->pp_config.denoise2d.denoise_enable = 1;
3397         streamInfo->pp_config.denoise2d.process_plates =
3398                 mParameters.getDenoiseProcessPlate(CAM_INTF_PARM_WAVELET_DENOISE);
3399     }
3400 
3401     if (!((needReprocess()) && (CAM_STREAM_TYPE_SNAPSHOT == stream_type ||
3402             CAM_STREAM_TYPE_RAW == stream_type))) {
3403         if (gCamCapability[mCameraId]->qcom_supported_feature_mask &
3404                 CAM_QCOM_FEATURE_CROP)
3405             streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
3406         if (gCamCapability[mCameraId]->qcom_supported_feature_mask &
3407                 CAM_QCOM_FEATURE_SCALE)
3408             streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
3409     }
3410     streamInfo->aux_str_info = NULL;
3411 
3412     LOGH("type %d, fmt %d, dim %dx%d, num_bufs %d mask = 0x%x is_type %d\n",
3413            stream_type, streamInfo->fmt, streamInfo->dim.width,
3414            streamInfo->dim.height, streamInfo->num_bufs,
3415            streamInfo->pp_config.feature_mask,
3416            streamInfo->is_type);
3417 
3418     return rc;
3419 }
3420 
3421 /*===========================================================================
3422  * FUNCTION   : allocateStreamInfoBuf
3423  *
3424  * DESCRIPTION: alocate stream info buffer
3425  *
3426  * PARAMETERS :
3427  *   @stream_type  : type of stream
3428  *   @bufCount       : stream info buffer count
3429  *
3430  * RETURN     : ptr to a memory obj that holds stream info buffer.
3431  *              NULL if failed
3432  *==========================================================================*/
allocateStreamInfoBuf(cam_stream_type_t stream_type,uint8_t bufCount)3433 QCameraHeapMemory *QCamera2HardwareInterface::allocateStreamInfoBuf(
3434         cam_stream_type_t stream_type, uint8_t bufCount)
3435 {
3436     int rc = NO_ERROR;
3437 
3438     QCameraHeapMemory *streamInfoBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
3439     if (!streamInfoBuf) {
3440         LOGE("allocateStreamInfoBuf: Unable to allocate streamInfo object");
3441         return NULL;
3442     }
3443 
3444     if (bufCount > MM_CAMERA_MAX_CAM_CNT) {
3445         LOGE("buffer count should be lesser than max camera : %d", bufCount);
3446         return NULL;
3447     }
3448     rc = streamInfoBuf->allocate(bufCount, sizeof(cam_stream_info_t), NON_SECURE);
3449     if (rc < 0) {
3450         LOGE("allocateStreamInfoBuf: Failed to allocate stream info memory");
3451         delete streamInfoBuf;
3452         return NULL;
3453     }
3454 
3455     for (uint8_t i = 0; i < bufCount; i++) {
3456         cam_stream_info_t *streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(i);
3457         memset(streamInfo, 0, sizeof(cam_stream_info_t));
3458         rc = initStreamInfoBuf(stream_type, streamInfo);
3459         if (rc < 0) {
3460             LOGE("initStreamInfoBuf failed");
3461             delete streamInfoBuf;
3462             return NULL;
3463         }
3464     }
3465 
3466     cam_stream_info_t *streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(0);
3467     if (bufCount == MM_CAMERA_MAX_CAM_CNT) {
3468         cam_stream_info_t *s_streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(1);
3469         streamInfo->aux_str_info = s_streamInfo;
3470     }
3471 
3472     if (streamInfo->aux_str_info != NULL) {
3473         /*Update StreamInfo for Aux camera*/
3474         streamInfo->aux_str_info->buf_cnt = getBufNumForAux(stream_type);
3475         streamInfo->num_bufs += streamInfo->aux_str_info->buf_cnt;
3476         streamInfo->aux_str_info->num_bufs += streamInfo->aux_str_info->buf_cnt;
3477     }
3478     return streamInfoBuf;
3479 }
3480 
3481 /*===========================================================================
3482  * FUNCTION   : allocateStreamUserBuf
3483  *
3484  * DESCRIPTION: allocate user ptr for stream buffers
3485  *
3486  * PARAMETERS :
3487  *   @streamInfo  : stream info structure
3488  *
3489  * RETURN     : ptr to a memory obj that holds stream info buffer.
3490  *                    NULL if failed
3491 
3492  *==========================================================================*/
allocateStreamUserBuf(cam_stream_info_t * streamInfo)3493 QCameraMemory *QCamera2HardwareInterface::allocateStreamUserBuf(
3494         cam_stream_info_t *streamInfo)
3495 {
3496     int rc = NO_ERROR;
3497     QCameraMemory *mem = NULL;
3498     int size = 0;
3499 
3500     if (streamInfo->streaming_mode != CAM_STREAMING_MODE_BATCH) {
3501         LOGE("Stream is not in BATCH mode. Invalid Stream");
3502         return NULL;
3503     }
3504 
3505     // Allocate stream user buffer memory object
3506     switch (streamInfo->stream_type) {
3507     case CAM_STREAM_TYPE_VIDEO: {
3508         QCameraVideoMemory *video_mem = new QCameraVideoMemory(
3509                 mGetMemory, FALSE, QCAMERA_MEM_TYPE_BATCH);
3510         if (video_mem == NULL) {
3511             LOGE("Out of memory for video obj");
3512             return NULL;
3513         }
3514         /*
3515         *   numFDs = BATCH size
3516         *  numInts = 5  // OFFSET, SIZE, USAGE, TIMESTAMP, FORMAT
3517         */
3518         rc = video_mem->allocateMeta(streamInfo->num_bufs,
3519                 mParameters.getBufBatchCount(), VIDEO_METADATA_NUM_INTS);
3520         if (rc < 0) {
3521             LOGE("allocateMeta failed");
3522             delete video_mem;
3523             return NULL;
3524         }
3525         int usage = 0;
3526         cam_format_t fmt;
3527         mParameters.getStreamFormat(CAM_STREAM_TYPE_VIDEO, fmt);
3528         if(mParameters.isUBWCEnabled() && (fmt == CAM_FORMAT_YUV_420_NV12_UBWC)) {
3529             usage = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
3530         }
3531         video_mem->setVideoInfo(usage, fmt);
3532         mem = static_cast<QCameraMemory *>(video_mem);
3533     }
3534     break;
3535 
3536     case CAM_STREAM_TYPE_PREVIEW:
3537     case CAM_STREAM_TYPE_POSTVIEW:
3538     case CAM_STREAM_TYPE_ANALYSIS:
3539     case CAM_STREAM_TYPE_SNAPSHOT:
3540     case CAM_STREAM_TYPE_RAW:
3541     case CAM_STREAM_TYPE_METADATA:
3542     case CAM_STREAM_TYPE_OFFLINE_PROC:
3543     case CAM_STREAM_TYPE_CALLBACK:
3544         LOGE("Stream type Not supported.for BATCH processing");
3545     break;
3546 
3547     case CAM_STREAM_TYPE_DEFAULT:
3548     case CAM_STREAM_TYPE_MAX:
3549     default:
3550         break;
3551     }
3552     if (!mem) {
3553         LOGE("Failed to allocate mem");
3554         return NULL;
3555     }
3556 
3557     /*Size of this buffer will be number of batch buffer */
3558     size = PAD_TO_SIZE((streamInfo->num_bufs * streamInfo->user_buf_info.size),
3559             CAM_PAD_TO_4K);
3560 
3561     LOGH("Allocating BATCH Buffer count = %d", streamInfo->num_bufs);
3562 
3563     if (size > 0) {
3564         // Allocating one buffer for all batch buffers
3565         rc = mem->allocate(1, size, NON_SECURE);
3566         if (rc < 0) {
3567             delete mem;
3568             return NULL;
3569         }
3570     }
3571     return mem;
3572 }
3573 
3574 
3575 /*===========================================================================
3576  * FUNCTION   : waitForDeferredAlloc
3577  *
3578  * DESCRIPTION: Wait for deferred allocation, if applicable
3579  *              (applicable only for metadata buffers so far)
3580  *
3581  * PARAMETERS :
3582  *   @stream_type  : type of stream to (possibly) wait for
3583  *
3584  * RETURN     : None
3585  *==========================================================================*/
waitForDeferredAlloc(cam_stream_type_t stream_type)3586 void QCamera2HardwareInterface::waitForDeferredAlloc(cam_stream_type_t stream_type)
3587 {
3588     if (stream_type == CAM_STREAM_TYPE_METADATA) {
3589         waitDeferredWork(mMetadataAllocJob);
3590     }
3591 }
3592 
3593 
3594 /*===========================================================================
3595  * FUNCTION   : setPreviewWindow
3596  *
3597  * DESCRIPTION: set preview window impl
3598  *
3599  * PARAMETERS :
3600  *   @window  : ptr to window ops table struct
3601  *
3602  * RETURN     : int32_t type of status
3603  *              NO_ERROR  -- success
3604  *              none-zero failure code
3605  *==========================================================================*/
setPreviewWindow(struct preview_stream_ops * window)3606 int QCamera2HardwareInterface::setPreviewWindow(
3607         struct preview_stream_ops *window)
3608 {
3609     mPreviewWindow = window;
3610     return NO_ERROR;
3611 }
3612 
3613 /*===========================================================================
3614  * FUNCTION   : setCallBacks
3615  *
3616  * DESCRIPTION: set callbacks impl
3617  *
3618  * PARAMETERS :
3619  *   @notify_cb  : notify cb
3620  *   @data_cb    : data cb
3621  *   @data_cb_timestamp : data cb with time stamp
3622  *   @get_memory : request memory ops table
3623  *   @user       : user data ptr
3624  *
3625  * RETURN     : int32_t type of status
3626  *              NO_ERROR  -- success
3627  *              none-zero failure code
3628  *==========================================================================*/
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)3629 int QCamera2HardwareInterface::setCallBacks(camera_notify_callback notify_cb,
3630                                             camera_data_callback data_cb,
3631                                             camera_data_timestamp_callback data_cb_timestamp,
3632                                             camera_request_memory get_memory,
3633                                             void *user)
3634 {
3635     mNotifyCb        = notify_cb;
3636     mDataCb          = data_cb;
3637     mDataCbTimestamp = data_cb_timestamp;
3638     mGetMemory       = get_memory;
3639     mCallbackCookie  = user;
3640     m_cbNotifier.setCallbacks(notify_cb, data_cb, data_cb_timestamp, user);
3641     return NO_ERROR;
3642 }
3643 
3644 /*===========================================================================
3645  * FUNCTION   : setJpegCallBacks
3646  *
3647  * DESCRIPTION: set JPEG callbacks impl
3648  *
3649  * PARAMETERS :
3650  *   @jpegCb  : Jpeg callback method
3651  *   @callbackCookie    : callback cookie
3652  *
3653  * RETURN     : int32_t type of status
3654  *              NO_ERROR  -- success
3655  *              none-zero failure code
3656  *==========================================================================*/
setJpegCallBacks(jpeg_data_callback jpegCb,void * callbackCookie)3657 void QCamera2HardwareInterface::setJpegCallBacks(jpeg_data_callback jpegCb,
3658                                             void *callbackCookie)
3659 {
3660     LOGH("camera id %d", getCameraId());
3661     mJpegCb        = jpegCb;
3662     mJpegCallbackCookie  = callbackCookie;
3663     m_cbNotifier.setJpegCallBacks(mJpegCb, mJpegCallbackCookie);
3664 }
3665 
3666 /*===========================================================================
3667  * FUNCTION   : enableMsgType
3668  *
3669  * DESCRIPTION: enable msg type impl
3670  *
3671  * PARAMETERS :
3672  *   @msg_type  : msg type mask to be enabled
3673  *
3674  * RETURN     : int32_t type of status
3675  *              NO_ERROR  -- success
3676  *              none-zero failure code
3677  *==========================================================================*/
enableMsgType(int32_t msg_type)3678 int QCamera2HardwareInterface::enableMsgType(int32_t msg_type)
3679 {
3680     int32_t rc = NO_ERROR;
3681 
3682     if (mParameters.isUBWCEnabled()) {
3683         /*Need Special CALLBACK stream incase application requesting for
3684               Preview callback  in UBWC case*/
3685         if (!(msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) &&
3686                 (msg_type & CAMERA_MSG_PREVIEW_FRAME)) {
3687             // Start callback channel only when preview/zsl channel is active
3688             QCameraChannel* previewCh = NULL;
3689             if (isZSLMode() && (getRecordingHintValue() != true)) {
3690                 previewCh = m_channels[QCAMERA_CH_TYPE_ZSL];
3691             } else {
3692                 previewCh = m_channels[QCAMERA_CH_TYPE_PREVIEW];
3693             }
3694             QCameraChannel* callbackCh = m_channels[QCAMERA_CH_TYPE_CALLBACK];
3695             if ((callbackCh != NULL) &&
3696                     (previewCh != NULL) && previewCh->isActive()) {
3697                 rc = startChannel(QCAMERA_CH_TYPE_CALLBACK);
3698                 if (rc != NO_ERROR) {
3699                     LOGE("START Callback Channel failed");
3700                 }
3701             }
3702         }
3703     }
3704     mMsgEnabled |= msg_type;
3705     LOGH("(0x%x) : mMsgEnabled = 0x%x rc = %d", msg_type , mMsgEnabled, rc);
3706     return rc;
3707 }
3708 
3709 /*===========================================================================
3710  * FUNCTION   : disableMsgType
3711  *
3712  * DESCRIPTION: disable msg type impl
3713  *
3714  * PARAMETERS :
3715  *   @msg_type  : msg type mask to be disabled
3716  *
3717  * RETURN     : int32_t type of status
3718  *              NO_ERROR  -- success
3719  *              none-zero failure code
3720  *==========================================================================*/
disableMsgType(int32_t msg_type)3721 int QCamera2HardwareInterface::disableMsgType(int32_t msg_type)
3722 {
3723     int32_t rc = NO_ERROR;
3724 
3725     if (mParameters.isUBWCEnabled()) {
3726         /*STOP CALLBACK STREAM*/
3727         if ((msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) &&
3728                 (msg_type & CAMERA_MSG_PREVIEW_FRAME)) {
3729             // Stop callback channel only if it is active
3730             if ((m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL) &&
3731                    (m_channels[QCAMERA_CH_TYPE_CALLBACK]->isActive())) {
3732                 rc = stopChannel(QCAMERA_CH_TYPE_CALLBACK);
3733                 if (rc != NO_ERROR) {
3734                     LOGE("STOP Callback Channel failed");
3735                 }
3736             }
3737         }
3738     }
3739     mMsgEnabled &= ~msg_type;
3740     LOGH("(0x%x) : mMsgEnabled = 0x%x rc = %d", msg_type , mMsgEnabled, rc);
3741     return rc;
3742 }
3743 
3744 /*===========================================================================
3745  * FUNCTION   : msgTypeEnabled
3746  *
3747  * DESCRIPTION: impl to determine if certain msg_type is enabled
3748  *
3749  * PARAMETERS :
3750  *   @msg_type  : msg type mask
3751  *
3752  * RETURN     : 0 -- not enabled
3753  *              none 0 -- enabled
3754  *==========================================================================*/
msgTypeEnabled(int32_t msg_type)3755 int QCamera2HardwareInterface::msgTypeEnabled(int32_t msg_type)
3756 {
3757     return (mMsgEnabled & msg_type);
3758 }
3759 
3760 /*===========================================================================
3761  * FUNCTION   : msgTypeEnabledWithLock
3762  *
3763  * DESCRIPTION: impl to determine if certain msg_type is enabled with lock
3764  *
3765  * PARAMETERS :
3766  *   @msg_type  : msg type mask
3767  *
3768  * RETURN     : 0 -- not enabled
3769  *              none 0 -- enabled
3770  *==========================================================================*/
msgTypeEnabledWithLock(int32_t msg_type)3771 int QCamera2HardwareInterface::msgTypeEnabledWithLock(int32_t msg_type)
3772 {
3773     int enabled = 0;
3774     lockAPI();
3775     enabled = mMsgEnabled & msg_type;
3776     unlockAPI();
3777     return enabled;
3778 }
3779 
3780 /*===========================================================================
3781  * FUNCTION   : startPreview
3782  *
3783  * DESCRIPTION: start preview impl
3784  *
3785  * PARAMETERS : none
3786  *
3787  * RETURN     : int32_t type of status
3788  *              NO_ERROR  -- success
3789  *              none-zero failure code
3790  *==========================================================================*/
startPreview()3791 int QCamera2HardwareInterface::startPreview()
3792 {
3793     KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_STARTPREVIEW);
3794     int32_t rc = NO_ERROR;
3795 
3796     LOGI("E ZSL = %d Recording Hint = %d", mParameters.isZSLMode(),
3797             mParameters.getRecordingHintValue());
3798 
3799     m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_START_PREVIEW);
3800 
3801     updateThermalLevel((void *)&mThermalLevel);
3802 
3803     setDisplayFrameSkip();
3804 
3805     // start preview stream
3806     if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) {
3807         rc = startChannel(QCAMERA_CH_TYPE_ZSL);
3808     } else {
3809         rc = startChannel(QCAMERA_CH_TYPE_PREVIEW);
3810     }
3811 
3812     if (rc != NO_ERROR) {
3813         LOGE("failed to start channels");
3814         m_perfLockMgr.releasePerfLock(PERF_LOCK_START_PREVIEW);
3815         return rc;
3816     }
3817 
3818     if ((msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME))
3819             && (m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL)) {
3820         rc = startChannel(QCAMERA_CH_TYPE_CALLBACK);
3821         if (rc != NO_ERROR) {
3822             LOGE("failed to start callback stream");
3823             stopChannel(QCAMERA_CH_TYPE_ZSL);
3824             stopChannel(QCAMERA_CH_TYPE_PREVIEW);
3825             m_perfLockMgr.releasePerfLock(PERF_LOCK_START_PREVIEW);
3826             return rc;
3827         }
3828     }
3829 
3830     updatePostPreviewParameters();
3831     m_stateMachine.setPreviewCallbackNeeded(true);
3832 
3833     // if job id is non-zero, that means the postproc init job is already
3834     // pending or complete
3835     if (mInitPProcJob == 0) {
3836         mInitPProcJob = deferPPInit();
3837         if (mInitPProcJob == 0) {
3838             LOGE("Unable to initialize postprocessor, mCameraHandle = %p",
3839                      mCameraHandle);
3840             rc = -ENOMEM;
3841             m_perfLockMgr.releasePerfLock(PERF_LOCK_START_PREVIEW);
3842             return rc;
3843         }
3844     }
3845 
3846     LOGI("X rc = %d", rc);
3847     return rc;
3848 }
3849 
updatePostPreviewParameters()3850 int32_t QCamera2HardwareInterface::updatePostPreviewParameters() {
3851     // Enable OIS only in Camera mode and 4k2k camcoder mode
3852     int32_t rc = NO_ERROR;
3853     rc = mParameters.updateOisValue(1);
3854     return NO_ERROR;
3855 }
3856 
3857 /*===========================================================================
3858  * FUNCTION   : stopPreview
3859  *
3860  * DESCRIPTION: stop preview impl
3861  *
3862  * PARAMETERS : none
3863  *
3864  * RETURN     : int32_t type of status
3865  *              NO_ERROR  -- success
3866  *              none-zero failure code
3867  *==========================================================================*/
stopPreview()3868 int QCamera2HardwareInterface::stopPreview()
3869 {
3870     KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_STOPPREVIEW);
3871     LOGI("E");
3872     mNumPreviewFaces = -1;
3873     mActiveAF = false;
3874 
3875     // Disable power Hint for preview
3876     m_perfLockMgr.releasePerfLock(PERF_LOCK_POWERHINT_PREVIEW);
3877 
3878     m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_STOP_PREVIEW);
3879 
3880     // stop preview stream
3881     stopChannel(QCAMERA_CH_TYPE_CALLBACK);
3882     stopChannel(QCAMERA_CH_TYPE_ZSL);
3883     stopChannel(QCAMERA_CH_TYPE_PREVIEW);
3884     stopChannel(QCAMERA_CH_TYPE_RAW);
3885 
3886     m_cbNotifier.flushPreviewNotifications();
3887     //add for ts makeup
3888 #ifdef TARGET_TS_MAKEUP
3889     ts_makeup_finish();
3890 #endif
3891     // delete all channels from preparePreview
3892     unpreparePreview();
3893 
3894     m_perfLockMgr.releasePerfLock(PERF_LOCK_STOP_PREVIEW);
3895     LOGI("X");
3896     return NO_ERROR;
3897 }
3898 
3899 /*===========================================================================
3900  * FUNCTION   : storeMetaDataInBuffers
3901  *
3902  * DESCRIPTION: enable store meta data in buffers for video frames impl
3903  *
3904  * PARAMETERS :
3905  *   @enable  : flag if need enable
3906  *
3907  * RETURN     : int32_t type of status
3908  *              NO_ERROR  -- success
3909  *              none-zero failure code
3910  *==========================================================================*/
storeMetaDataInBuffers(int enable)3911 int QCamera2HardwareInterface::storeMetaDataInBuffers(int enable)
3912 {
3913     mStoreMetaDataInFrame = enable;
3914     return NO_ERROR;
3915 }
3916 
3917 /*===========================================================================
3918  * FUNCTION   : preStartRecording
3919  *
3920  * DESCRIPTION: Prepare start recording impl
3921  *
3922  * PARAMETERS : none
3923  *
3924  * RETURN     : int32_t type of status
3925  *              NO_ERROR  -- success
3926  *              none-zero failure code
3927  *==========================================================================*/
preStartRecording()3928 int QCamera2HardwareInterface::preStartRecording()
3929 {
3930     int32_t rc = NO_ERROR;
3931     LOGH("E");
3932     if (mParameters.getRecordingHintValue() == false) {
3933 
3934         // Give HWI control to restart preview only in single camera mode.
3935         // In dual-cam mode, this control belongs to muxer.
3936         if (getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
3937             LOGH("start recording when hint is false, stop preview first");
3938             stopPreview();
3939 
3940             // Set recording hint to TRUE
3941             mParameters.updateRecordingHintValue(TRUE);
3942             rc = preparePreview();
3943             if (rc == NO_ERROR) {
3944                 rc = startPreview();
3945             }
3946         }
3947         else
3948         {
3949             // For dual cam mode, update the flag mPreviewRestartNeeded to true
3950             // Restart control will be handled by muxer.
3951             mPreviewRestartNeeded = true;
3952         }
3953     }
3954 
3955     LOGH("X rc = %d", rc);
3956     return rc;
3957 }
3958 
3959 /*===========================================================================
3960  * FUNCTION   : startRecording
3961  *
3962  * DESCRIPTION: start recording impl
3963  *
3964  * PARAMETERS : none
3965  *
3966  * RETURN     : int32_t type of status
3967  *              NO_ERROR  -- success
3968  *              none-zero failure code
3969  *==========================================================================*/
startRecording()3970 int QCamera2HardwareInterface::startRecording()
3971 {
3972     int32_t rc = NO_ERROR;
3973 
3974     LOGI("E");
3975 
3976     m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_START_RECORDING);
3977 
3978     //link meta stream with video channel if low power mode.
3979     if (isLowPowerMode()) {
3980         // Find and try to link a metadata stream from preview channel
3981         QCameraChannel *pMetaChannel = NULL;
3982         QCameraStream *pMetaStream = NULL;
3983         QCameraChannel *pVideoChannel = m_channels[QCAMERA_CH_TYPE_VIDEO];
3984 
3985         if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
3986             pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
3987             uint32_t streamNum = pMetaChannel->getNumOfStreams();
3988             QCameraStream *pStream = NULL;
3989             for (uint32_t i = 0 ; i < streamNum ; i++ ) {
3990                 pStream = pMetaChannel->getStreamByIndex(i);
3991                 if ((NULL != pStream) &&
3992                         (CAM_STREAM_TYPE_METADATA == pStream->getMyType())) {
3993                     pMetaStream = pStream;
3994                     break;
3995                 }
3996             }
3997         }
3998 
3999         if ((NULL != pMetaChannel) && (NULL != pMetaStream)) {
4000             rc = pVideoChannel->linkStream(pMetaChannel, pMetaStream);
4001             if (NO_ERROR != rc) {
4002                 LOGW("Metadata stream link failed %d", rc);
4003             }
4004         }
4005     }
4006 
4007     if (rc == NO_ERROR) {
4008         rc = startChannel(QCAMERA_CH_TYPE_VIDEO);
4009     }
4010 
4011     if (mParameters.isTNRSnapshotEnabled() && !isLowPowerMode()) {
4012         QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
4013         if (!mParameters.is4k2kVideoResolution()) {
4014             // Find and try to link a metadata stream from preview channel
4015             QCameraChannel *pMetaChannel = NULL;
4016             QCameraStream *pMetaStream = NULL;
4017 
4018             if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
4019                 pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
4020                 uint32_t streamNum = pMetaChannel->getNumOfStreams();
4021                 QCameraStream *pStream = NULL;
4022                 for (uint32_t i = 0 ; i < streamNum ; i++ ) {
4023                     pStream = pMetaChannel->getStreamByIndex(i);
4024                     if ((NULL != pStream) &&
4025                             (CAM_STREAM_TYPE_METADATA ==
4026                             pStream->getMyType())) {
4027                         pMetaStream = pStream;
4028                         break;
4029                     }
4030                 }
4031             }
4032 
4033             if ((NULL != pMetaChannel) && (NULL != pMetaStream)) {
4034                 rc = pChannel->linkStream(pMetaChannel, pMetaStream);
4035                 if (NO_ERROR != rc) {
4036                     LOGW("Metadata stream link failed %d", rc);
4037                 }
4038             }
4039         }
4040         LOGH("START snapshot Channel for TNR processing");
4041         rc = pChannel->start();
4042     }
4043 
4044     m_perfLockMgr.releasePerfLock(PERF_LOCK_START_RECORDING);
4045 
4046     if (rc == NO_ERROR) {
4047         // Set power Hint for video encoding
4048         m_perfLockMgr.acquirePerfLock(PERF_LOCK_POWERHINT_ENCODE, 0);
4049     }
4050 
4051     LOGI("X rc = %d", rc);
4052     return rc;
4053 }
4054 
4055 /*===========================================================================
4056  * FUNCTION   : stopRecording
4057  *
4058  * DESCRIPTION: stop recording impl
4059  *
4060  * PARAMETERS : none
4061  *
4062  * RETURN     : int32_t type of status
4063  *              NO_ERROR  -- success
4064  *              none-zero failure code
4065  *==========================================================================*/
stopRecording()4066 int QCamera2HardwareInterface::stopRecording()
4067 {
4068     LOGI("E");
4069 
4070     // Disable power hint for video encoding
4071     m_perfLockMgr.releasePerfLock(PERF_LOCK_POWERHINT_ENCODE);
4072 
4073     m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_STOP_RECORDING);
4074 
4075     // stop snapshot channel
4076     if (mParameters.isTNRSnapshotEnabled()) {
4077         LOGH("STOP snapshot Channel for TNR processing");
4078         stopChannel(QCAMERA_CH_TYPE_SNAPSHOT);
4079     }
4080     int rc = stopChannel(QCAMERA_CH_TYPE_VIDEO);
4081 
4082     m_cbNotifier.flushVideoNotifications();
4083 
4084     m_perfLockMgr.releasePerfLock(PERF_LOCK_STOP_RECORDING);
4085 
4086     LOGI("X rc = %d", rc);
4087     return rc;
4088 }
4089 
4090 /*===========================================================================
4091  * FUNCTION   : releaseRecordingFrame
4092  *
4093  * DESCRIPTION: return video frame impl
4094  *
4095  * PARAMETERS :
4096  *   @opaque  : ptr to video frame to be returned
4097  *
4098  * RETURN     : int32_t type of status
4099  *              NO_ERROR  -- success
4100  *              none-zero failure code
4101  *==========================================================================*/
releaseRecordingFrame(const void * opaque)4102 int QCamera2HardwareInterface::releaseRecordingFrame(const void * opaque)
4103 {
4104     int32_t rc = UNKNOWN_ERROR;
4105     QCameraVideoChannel *pChannel =
4106             (QCameraVideoChannel *)m_channels[QCAMERA_CH_TYPE_VIDEO];
4107     LOGD("opaque data = %p",opaque);
4108 
4109     if(pChannel != NULL) {
4110         rc = pChannel->releaseFrame(opaque, mStoreMetaDataInFrame > 0);
4111     }
4112     return rc;
4113 }
4114 
4115 /*===========================================================================
4116  * FUNCTION   : autoFocus
4117  *
4118  * DESCRIPTION: start auto focus impl
4119  *
4120  * PARAMETERS : none
4121  *
4122  * RETURN     : int32_t type of status
4123  *              NO_ERROR  -- success
4124  *              none-zero failure code
4125  *==========================================================================*/
autoFocus()4126 int QCamera2HardwareInterface::autoFocus()
4127 {
4128     int rc = NO_ERROR;
4129     cam_focus_mode_type focusMode = mParameters.getFocusMode();
4130     LOGH("E");
4131 
4132     switch (focusMode) {
4133     case CAM_FOCUS_MODE_AUTO:
4134     case CAM_FOCUS_MODE_MACRO:
4135     case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
4136     case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
4137         mActiveAF = true;
4138         LOGI("Send AUTO FOCUS event. focusMode=%d, m_currentFocusState=%d",
4139                 focusMode, m_currentFocusState);
4140         rc = mCameraHandle->ops->do_auto_focus(mCameraHandle->camera_handle);
4141         break;
4142     case CAM_FOCUS_MODE_INFINITY:
4143     case CAM_FOCUS_MODE_FIXED:
4144     case CAM_FOCUS_MODE_EDOF:
4145     default:
4146         LOGI("No ops in focusMode (%d)", focusMode);
4147         rc = sendEvtNotify(CAMERA_MSG_FOCUS, true, 0);
4148         break;
4149     }
4150 
4151     if (NO_ERROR != rc) {
4152         mActiveAF = false;
4153     }
4154     LOGH("X rc = %d", rc);
4155     return rc;
4156 }
4157 
4158 /*===========================================================================
4159  * FUNCTION   : cancelAutoFocus
4160  *
4161  * DESCRIPTION: cancel auto focus impl
4162  *
4163  * PARAMETERS : none
4164  *
4165  * RETURN     : int32_t type of status
4166  *              NO_ERROR  -- success
4167  *              none-zero failure code
4168  *==========================================================================*/
cancelAutoFocus()4169 int QCamera2HardwareInterface::cancelAutoFocus()
4170 {
4171     int rc = NO_ERROR;
4172     cam_focus_mode_type focusMode = mParameters.getFocusMode();
4173 
4174     switch (focusMode) {
4175     case CAM_FOCUS_MODE_AUTO:
4176     case CAM_FOCUS_MODE_MACRO:
4177     case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
4178     case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
4179         mActiveAF = false;
4180         rc = mCameraHandle->ops->cancel_auto_focus(mCameraHandle->camera_handle);
4181         break;
4182     case CAM_FOCUS_MODE_INFINITY:
4183     case CAM_FOCUS_MODE_FIXED:
4184     case CAM_FOCUS_MODE_EDOF:
4185     default:
4186         LOGD("No ops in focusMode (%d)", focusMode);
4187         break;
4188     }
4189     return rc;
4190 }
4191 
4192 /*===========================================================================
4193  * FUNCTION   : processUFDumps
4194  *
4195  * DESCRIPTION: process UF jpeg dumps for refocus support
4196  *
4197  * PARAMETERS :
4198  *   @evt     : payload of jpeg event, including information about jpeg encoding
4199  *              status, jpeg size and so on.
4200  *
4201  * RETURN     : int32_t type of status
4202  *              NO_ERROR  -- success
4203  *              none-zero failure code
4204  *
4205  * NOTE       : none
4206  *==========================================================================*/
processUFDumps(qcamera_jpeg_evt_payload_t * evt)4207 bool QCamera2HardwareInterface::processUFDumps(qcamera_jpeg_evt_payload_t *evt)
4208 {
4209    bool ret = true;
4210    if (mParameters.isUbiRefocus()) {
4211        int index = (int)getOutputImageCount();
4212        bool allFocusImage = (index == ((int)mParameters.getRefocusOutputCount() - 1));
4213        char name[FILENAME_MAX];
4214 
4215        camera_memory_t *jpeg_mem = NULL;
4216        omx_jpeg_ouput_buf_t *jpeg_out = NULL;
4217        size_t dataLen;
4218        uint8_t *dataPtr;
4219        if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
4220            LOGE("Init PProc Deferred work failed");
4221            return false;
4222        }
4223        if (!m_postprocessor.getJpegMemOpt()) {
4224            dataLen = evt->out_data.buf_filled_len;
4225            dataPtr = evt->out_data.buf_vaddr;
4226        } else {
4227            jpeg_out  = (omx_jpeg_ouput_buf_t*) evt->out_data.buf_vaddr;
4228            if (!jpeg_out) {
4229               LOGE("Null pointer detected");
4230               return false;
4231            }
4232            jpeg_mem = (camera_memory_t *)jpeg_out->mem_hdl;
4233            if (!jpeg_mem) {
4234               LOGE("Null pointer detected");
4235               return false;
4236            }
4237            dataPtr = (uint8_t *)jpeg_mem->data;
4238            dataLen = jpeg_mem->size;
4239        }
4240 
4241        if (allFocusImage)  {
4242            snprintf(name, sizeof(name), "AllFocusImage");
4243            index = -1;
4244        } else {
4245            snprintf(name, sizeof(name), "%d", 0);
4246        }
4247        CAM_DUMP_TO_FILE(QCAMERA_DUMP_FRM_LOCATION"ubifocus", name, index, "jpg",
4248            dataPtr, dataLen);
4249        LOGD("Dump the image %d %d allFocusImage %d",
4250            getOutputImageCount(), index, allFocusImage);
4251        setOutputImageCount(getOutputImageCount() + 1);
4252        if (!allFocusImage) {
4253            ret = false;
4254        }
4255    }
4256    return ret;
4257 }
4258 
4259 /*===========================================================================
4260  * FUNCTION   : unconfigureAdvancedCapture
4261  *
4262  * DESCRIPTION: unconfigure Advanced Capture.
4263  *
4264  * PARAMETERS : none
4265  *
4266  * RETURN     : int32_t type of status
4267  *              NO_ERROR  -- success
4268  *              none-zero failure code
4269  *==========================================================================*/
unconfigureAdvancedCapture()4270 int32_t QCamera2HardwareInterface::unconfigureAdvancedCapture()
4271 {
4272     int32_t rc = NO_ERROR;
4273 
4274     /*Disable Quadra CFA mode*/
4275     LOGH("Disabling Quadra CFA mode");
4276     mParameters.setQuadraCfaMode(false, true);
4277 
4278     if (mAdvancedCaptureConfigured) {
4279 
4280         mAdvancedCaptureConfigured = false;
4281 
4282         if(mIs3ALocked) {
4283             mParameters.set3ALock(false);
4284             mIs3ALocked = false;
4285         }
4286         if (mParameters.isHDREnabled() || mParameters.isAEBracketEnabled()) {
4287             rc = mParameters.setToneMapMode(true, true);
4288             if (rc != NO_ERROR) {
4289                 LOGW("Failed to enable tone map during HDR/AEBracketing");
4290             }
4291             mHDRBracketingEnabled = false;
4292             rc = mParameters.stopAEBracket();
4293         } else if ((mParameters.isChromaFlashEnabled())
4294                 || (mFlashConfigured && !mLongshotEnabled)
4295                 || (mLowLightConfigured == true)
4296                 || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
4297             rc = mParameters.resetFrameCapture(TRUE, mLowLightConfigured);
4298         } else if (mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
4299             rc = configureAFBracketing(false);
4300         } else if (mParameters.isOptiZoomEnabled()) {
4301             rc = mParameters.setAndCommitZoom(mZoomLevel);
4302             setDisplaySkip(FALSE, CAMERA_MAX_PARAM_APPLY_DELAY);
4303         } else if (mParameters.isStillMoreEnabled()) {
4304             cam_still_more_t stillmore_config = mParameters.getStillMoreSettings();
4305             stillmore_config.burst_count = 0;
4306             mParameters.setStillMoreSettings(stillmore_config);
4307 
4308             /* If SeeMore is running, it will handle re-enabling tone map */
4309             if (!mParameters.isSeeMoreEnabled() && !mParameters.isLTMForSeeMoreEnabled()) {
4310                 rc = mParameters.setToneMapMode(true, true);
4311                 if (rc != NO_ERROR) {
4312                     LOGW("Failed to enable tone map during StillMore");
4313                 }
4314             }
4315 
4316             /* Re-enable Tintless */
4317             mParameters.setTintless(true);
4318         } else {
4319             LOGW("No Advanced Capture feature enabled!!");
4320             rc = BAD_VALUE;
4321         }
4322     }
4323 
4324     return rc;
4325 }
4326 
4327 /*===========================================================================
4328  * FUNCTION   : configureAdvancedCapture
4329  *
4330  * DESCRIPTION: configure Advanced Capture.
4331  *
4332  * PARAMETERS : none
4333  *
4334  * RETURN     : int32_t type of status
4335  *              NO_ERROR  -- success
4336  *              none-zero failure code
4337  *==========================================================================*/
configureAdvancedCapture()4338 int32_t QCamera2HardwareInterface::configureAdvancedCapture()
4339 {
4340     LOGH("E");
4341     int32_t rc = NO_ERROR;
4342 
4343     rc = mParameters.checkFeatureConcurrency();
4344     if (rc != NO_ERROR) {
4345         LOGE("Cannot support Advanced capture modes");
4346         return rc;
4347     }
4348     /*Enable Quadra CFA mode*/
4349     LOGH("Enabling Quadra CFA mode");
4350     mParameters.setQuadraCfaMode(true, true);
4351 
4352     setOutputImageCount(0);
4353     mInputCount = 0;
4354     mAdvancedCaptureConfigured = true;
4355     /* Display should be disabled for advanced modes */
4356     bool bSkipDisplay = true;
4357 
4358     if (getRelatedCamSyncInfo()->mode == CAM_MODE_SECONDARY) {
4359         // no Advance capture settings for Aux camera
4360         LOGH("X Secondary Camera, no need to process!! ");
4361         return rc;
4362     }
4363 
4364     /* Do not stop display if in stillmore livesnapshot */
4365     if (mParameters.isStillMoreEnabled() &&
4366             mParameters.isSeeMoreEnabled()) {
4367         bSkipDisplay = false;
4368     }
4369     if (mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
4370         rc = configureAFBracketing();
4371     } else if (mParameters.isOptiZoomEnabled()) {
4372         rc = configureOptiZoom();
4373     } else if(mParameters.isHDREnabled()) {
4374         rc = configureHDRBracketing();
4375         if (mHDRBracketingEnabled) {
4376             rc = mParameters.setToneMapMode(false, true);
4377             if (rc != NO_ERROR) {
4378                 LOGW("Failed to disable tone map during HDR");
4379             }
4380         }
4381     } else if (mParameters.isAEBracketEnabled()) {
4382         rc = mParameters.setToneMapMode(false, true);
4383         if (rc != NO_ERROR) {
4384             LOGW("Failed to disable tone map during AEBracketing");
4385         }
4386         rc = configureAEBracketing();
4387     } else if (mParameters.isStillMoreEnabled()) {
4388         bSkipDisplay = false;
4389         rc = configureStillMore();
4390     } else if ((mParameters.isChromaFlashEnabled())
4391             || (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF)
4392             || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
4393         rc = mParameters.configFrameCapture(TRUE);
4394         if (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF) {
4395             mLowLightConfigured = true;
4396         }
4397     } else if (mFlashNeeded && !mLongshotEnabled) {
4398         rc = mParameters.configFrameCapture(TRUE);
4399         mFlashConfigured = true;
4400         bSkipDisplay = false;
4401     } else {
4402         LOGH("Advanced Capture feature not enabled!! ");
4403         mAdvancedCaptureConfigured = false;
4404         bSkipDisplay = false;
4405     }
4406 
4407     LOGH("Stop preview temporarily for advanced captures");
4408     setDisplaySkip(bSkipDisplay);
4409 
4410     LOGH("X rc = %d", rc);
4411     return rc;
4412 }
4413 
4414 /*===========================================================================
4415  * FUNCTION   : configureAFBracketing
4416  *
4417  * DESCRIPTION: configure AF Bracketing.
4418  *
4419  * PARAMETERS : none
4420  *
4421  * RETURN     : int32_t type of status
4422  *              NO_ERROR  -- success
4423  *              none-zero failure code
4424  *==========================================================================*/
configureAFBracketing(bool enable)4425 int32_t QCamera2HardwareInterface::configureAFBracketing(bool enable)
4426 {
4427     LOGH("E");
4428     int32_t rc = NO_ERROR;
4429     cam_af_bracketing_t *af_bracketing_need;
4430 
4431     if (mParameters.isUbiRefocus()) {
4432         af_bracketing_need =
4433                 &gCamCapability[mCameraId]->refocus_af_bracketing_need;
4434     } else {
4435         af_bracketing_need =
4436                 &gCamCapability[mCameraId]->ubifocus_af_bracketing_need;
4437     }
4438 
4439     //Enable AF Bracketing.
4440     cam_af_bracketing_t afBracket;
4441     memset(&afBracket, 0, sizeof(cam_af_bracketing_t));
4442     afBracket.enable = enable;
4443     afBracket.burst_count = af_bracketing_need->burst_count;
4444 
4445     for(int8_t i = 0; i < MAX_AF_BRACKETING_VALUES; i++) {
4446         afBracket.focus_steps[i] = af_bracketing_need->focus_steps[i];
4447         LOGH("focus_step[%d] = %d", i, afBracket.focus_steps[i]);
4448     }
4449     //Send cmd to backend to set AF Bracketing for Ubi Focus.
4450     rc = mParameters.commitAFBracket(afBracket);
4451     if ( NO_ERROR != rc ) {
4452         LOGE("cannot configure AF bracketing");
4453         return rc;
4454     }
4455     if (enable) {
4456         mParameters.set3ALock(true);
4457         mIs3ALocked = true;
4458     }
4459     LOGH("X rc = %d", rc);
4460     return rc;
4461 }
4462 
4463 /*===========================================================================
4464  * FUNCTION   : configureHDRBracketing
4465  *
4466  * DESCRIPTION: configure HDR Bracketing.
4467  *
4468  * PARAMETERS : none
4469  *
4470  * RETURN     : int32_t type of status
4471  *              NO_ERROR  -- success
4472  *              none-zero failure code
4473  *==========================================================================*/
configureHDRBracketing()4474 int32_t QCamera2HardwareInterface::configureHDRBracketing()
4475 {
4476     LOGH("E");
4477     int32_t rc = NO_ERROR;
4478 
4479     cam_hdr_bracketing_info_t& hdrBracketingSetting =
4480             gCamCapability[mCameraId]->hdr_bracketing_setting;
4481 
4482     // 'values' should be in "idx1,idx2,idx3,..." format
4483     uint32_t hdrFrameCount =
4484             hdrBracketingSetting.num_frames;
4485     LOGH("HDR values %d, %d frame count: %u",
4486           (int8_t) hdrBracketingSetting.exp_val.values[0],
4487           (int8_t) hdrBracketingSetting.exp_val.values[1],
4488           hdrFrameCount);
4489 
4490     // Enable AE Bracketing for HDR
4491     cam_exp_bracketing_t aeBracket;
4492     memset(&aeBracket, 0, sizeof(cam_exp_bracketing_t));
4493     aeBracket.mode =
4494         hdrBracketingSetting.exp_val.mode;
4495 
4496     if (aeBracket.mode == CAM_EXP_BRACKETING_ON) {
4497         mHDRBracketingEnabled = true;
4498     }
4499 
4500     String8 tmp;
4501     for (uint32_t i = 0; i < hdrFrameCount; i++) {
4502         tmp.appendFormat("%d",
4503             (int8_t) hdrBracketingSetting.exp_val.values[i]);
4504         tmp.append(",");
4505     }
4506     if (mParameters.isHDR1xFrameEnabled()
4507         && mParameters.isHDR1xExtraBufferNeeded()) {
4508             tmp.appendFormat("%d", 0);
4509             tmp.append(",");
4510     }
4511 
4512     if( !tmp.isEmpty() &&
4513         ( MAX_EXP_BRACKETING_LENGTH > tmp.length() ) ) {
4514         //Trim last comma
4515         memset(aeBracket.values, '\0', MAX_EXP_BRACKETING_LENGTH);
4516         memcpy(aeBracket.values, tmp.string(), tmp.length() - 1);
4517     }
4518 
4519     LOGH("HDR config values %s",
4520           aeBracket.values);
4521     rc = mParameters.setHDRAEBracket(aeBracket);
4522     if ( NO_ERROR != rc ) {
4523         LOGE("cannot configure HDR bracketing");
4524         return rc;
4525     }
4526     LOGH("X rc = %d", rc);
4527     return rc;
4528 }
4529 
4530 /*===========================================================================
4531  * FUNCTION   : configureAEBracketing
4532  *
4533  * DESCRIPTION: configure AE Bracketing.
4534  *
4535  * PARAMETERS : none
4536  *
4537  * RETURN     : int32_t type of status
4538  *              NO_ERROR  -- success
4539  *              none-zero failure code
4540  *==========================================================================*/
configureAEBracketing()4541 int32_t QCamera2HardwareInterface::configureAEBracketing()
4542 {
4543     LOGH("E");
4544     int32_t rc = NO_ERROR;
4545 
4546     rc = mParameters.setAEBracketing();
4547     if ( NO_ERROR != rc ) {
4548         LOGE("cannot configure AE bracketing");
4549         return rc;
4550     }
4551     LOGH("X rc = %d", rc);
4552     return rc;
4553 }
4554 
4555 /*===========================================================================
4556  * FUNCTION   : configureOptiZoom
4557  *
4558  * DESCRIPTION: configure Opti Zoom.
4559  *
4560  * PARAMETERS : none
4561  *
4562  * RETURN     : int32_t type of status
4563  *              NO_ERROR  -- success
4564  *              none-zero failure code
4565  *==========================================================================*/
configureOptiZoom()4566 int32_t QCamera2HardwareInterface::configureOptiZoom()
4567 {
4568     int32_t rc = NO_ERROR;
4569 
4570     //store current zoom level.
4571     mZoomLevel = mParameters.getParmZoomLevel();
4572 
4573     //set zoom level to 1x;
4574     mParameters.setAndCommitZoom(0);
4575 
4576     mParameters.set3ALock(true);
4577     mIs3ALocked = true;
4578 
4579     return rc;
4580 }
4581 
4582 /*===========================================================================
4583  * FUNCTION   : configureStillMore
4584  *
4585  * DESCRIPTION: configure StillMore.
4586  *
4587  * PARAMETERS : none
4588  *
4589  * RETURN     : int32_t type of status
4590  *              NO_ERROR  -- success
4591  *              none-zero failure code
4592  *==========================================================================*/
configureStillMore()4593 int32_t QCamera2HardwareInterface::configureStillMore()
4594 {
4595     int32_t rc = NO_ERROR;
4596     uint8_t burst_cnt = 0;
4597     cam_still_more_t stillmore_config;
4598     cam_still_more_t stillmore_cap;
4599 
4600     /* Disable Tone Map. If seemore is enabled, it will handle disabling it. */
4601     if (!mParameters.isSeeMoreEnabled() && !mParameters.isLTMForSeeMoreEnabled()) {
4602         rc = mParameters.setToneMapMode(false, true);
4603         if (rc != NO_ERROR) {
4604             LOGW("Failed to disable tone map during StillMore");
4605         }
4606     }
4607 
4608     /* Lock 3A */
4609     mParameters.set3ALock(true);
4610     mIs3ALocked = true;
4611 
4612     /* Disable Tintless */
4613     mParameters.setTintless(false);
4614 
4615     /* Initialize burst count from capability */
4616     stillmore_cap = mParameters.getStillMoreCapability();
4617     burst_cnt = stillmore_cap.max_burst_count;
4618 
4619     /* Reconfigure burst count from dynamic scene data */
4620     cam_dyn_img_data_t dynamic_img_data = mParameters.getDynamicImgData();
4621     if (dynamic_img_data.input_count >= stillmore_cap.min_burst_count &&
4622             dynamic_img_data.input_count <= stillmore_cap.max_burst_count) {
4623         burst_cnt = dynamic_img_data.input_count;
4624     }
4625 
4626     /* Reconfigure burst count in the case of liveshot */
4627     if (mParameters.isSeeMoreEnabled()) {
4628         burst_cnt = 1;
4629     }
4630 
4631     /* Reconfigure burst count from user input */
4632     char prop[PROPERTY_VALUE_MAX];
4633     property_get("persist.camera.imglib.stillmore", prop, "0");
4634     uint8_t burst_setprop = (uint32_t)atoi(prop);
4635     if (burst_setprop != 0)  {
4636        if ((burst_setprop < stillmore_cap.min_burst_count) ||
4637                (burst_setprop > stillmore_cap.max_burst_count)) {
4638            burst_cnt = stillmore_cap.max_burst_count;
4639        } else {
4640            burst_cnt = burst_setprop;
4641        }
4642     }
4643 
4644     memset(&stillmore_config, 0, sizeof(cam_still_more_t));
4645     stillmore_config.burst_count = burst_cnt;
4646     mParameters.setStillMoreSettings(stillmore_config);
4647 
4648     LOGH("Stillmore burst %d", burst_cnt);
4649 
4650     return rc;
4651 }
4652 
4653 /*===========================================================================
4654  * FUNCTION   : stopAdvancedCapture
4655  *
4656  * DESCRIPTION: stops advanced capture based on capture type
4657  *
4658  * PARAMETERS :
4659  *   @pChannel : channel.
4660  *
4661  * RETURN     : int32_t type of status
4662  *              NO_ERROR  -- success
4663  *              none-zero failure code
4664  *==========================================================================*/
stopAdvancedCapture(QCameraPicChannel * pChannel)4665 int32_t QCamera2HardwareInterface::stopAdvancedCapture(
4666         QCameraPicChannel *pChannel)
4667 {
4668     LOGH("stop bracketig");
4669     int32_t rc = NO_ERROR;
4670 
4671     if(mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
4672         rc = pChannel->stopAdvancedCapture(MM_CAMERA_AF_BRACKETING);
4673     } else if (mParameters.isChromaFlashEnabled()
4674             || (mFlashConfigured && !mLongshotEnabled)
4675             || (mLowLightConfigured == true)
4676             || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
4677         rc = pChannel->stopAdvancedCapture(MM_CAMERA_FRAME_CAPTURE);
4678         mFlashConfigured = false;
4679         mLowLightConfigured = false;
4680     } else if(mParameters.isHDREnabled()
4681             || mParameters.isAEBracketEnabled()) {
4682         rc = pChannel->stopAdvancedCapture(MM_CAMERA_AE_BRACKETING);
4683     } else if (mParameters.isOptiZoomEnabled()) {
4684         rc = pChannel->stopAdvancedCapture(MM_CAMERA_ZOOM_1X);
4685     } else if (mParameters.isStillMoreEnabled()) {
4686         LOGH("stopAdvancedCapture not needed for StillMore");
4687     } else {
4688         LOGH("No Advanced Capture feature enabled!");
4689         rc = BAD_VALUE;
4690     }
4691     return rc;
4692 }
4693 
4694 /*===========================================================================
4695  * FUNCTION   : startAdvancedCapture
4696  *
4697  * DESCRIPTION: starts advanced capture based on capture type
4698  *
4699  * PARAMETERS :
4700  *   @pChannel : channel.
4701  *
4702  * RETURN     : int32_t type of status
4703  *              NO_ERROR  -- success
4704  *              none-zero failure code
4705  *==========================================================================*/
startAdvancedCapture(QCameraPicChannel * pChannel)4706 int32_t QCamera2HardwareInterface::startAdvancedCapture(
4707         QCameraPicChannel *pChannel)
4708 {
4709     LOGH("Start bracketing");
4710     int32_t rc = NO_ERROR;
4711 
4712     if(mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
4713         rc = pChannel->startAdvancedCapture(MM_CAMERA_AF_BRACKETING);
4714     } else if (mParameters.isOptiZoomEnabled()) {
4715         rc = pChannel->startAdvancedCapture(MM_CAMERA_ZOOM_1X);
4716     } else if (mParameters.isStillMoreEnabled()) {
4717         LOGH("startAdvancedCapture not needed for StillMore");
4718     } else if (mParameters.isHDREnabled()
4719             || mParameters.isAEBracketEnabled()) {
4720         rc = pChannel->startAdvancedCapture(MM_CAMERA_AE_BRACKETING);
4721     } else if (mParameters.isChromaFlashEnabled()
4722             || (mFlashNeeded && !mLongshotEnabled)
4723             || (mLowLightConfigured == true)
4724             || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
4725         cam_capture_frame_config_t config = mParameters.getCaptureFrameConfig();
4726         rc = pChannel->startAdvancedCapture(MM_CAMERA_FRAME_CAPTURE, &config);
4727     } else {
4728         LOGE("No Advanced Capture feature enabled!");
4729         rc = BAD_VALUE;
4730     }
4731     return rc;
4732 }
4733 
4734 /*===========================================================================
4735  * FUNCTION   : preTakePicture
4736  *
4737  * DESCRIPTION: Prepare take picture impl, Restarts preview if necessary
4738  *
4739  * PARAMETERS : none
4740  *
4741  * RETURN     : int32_t type of status
4742  *              NO_ERROR  -- success
4743  *              none-zero failure code
4744  *==========================================================================*/
preTakePicture()4745 int QCamera2HardwareInterface::preTakePicture()
4746 {
4747     int32_t rc = NO_ERROR;
4748     LOGH("E");
4749     if (mParameters.getRecordingHintValue() == true) {
4750 
4751         // Give HWI control to restart preview only in single camera mode.
4752         // In dual-cam mode, this control belongs to muxer.
4753         if (getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
4754             LOGH("restart preview if rec hint is true and preview is running");
4755             stopPreview();
4756             mParameters.updateRecordingHintValue(FALSE);
4757             // start preview again
4758             rc = preparePreview();
4759             if (rc == NO_ERROR) {
4760                 rc = startPreview();
4761                 if (rc != NO_ERROR) {
4762                     unpreparePreview();
4763                 }
4764             }
4765         }
4766         else
4767         {
4768             // For dual cam mode, update the flag mPreviewRestartNeeded to true
4769             // Restart control will be handled by muxer.
4770             mPreviewRestartNeeded = true;
4771         }
4772     }
4773 
4774     LOGH("X rc = %d", rc);
4775     return rc;
4776 }
4777 
4778 /*===========================================================================
4779  * FUNCTION   : takePicture
4780  *
4781  * DESCRIPTION: take picture impl
4782  *
4783  * PARAMETERS : none
4784  *
4785  * RETURN     : int32_t type of status
4786  *              NO_ERROR  -- success
4787  *              none-zero failure code
4788  *==========================================================================*/
takePicture()4789 int QCamera2HardwareInterface::takePicture()
4790 {
4791     int rc = NO_ERROR;
4792 
4793     // Get total number for snapshots (retro + regular)
4794     uint8_t numSnapshots = mParameters.getNumOfSnapshots();
4795     // Get number of retro-active snapshots
4796     uint8_t numRetroSnapshots = mParameters.getNumOfRetroSnapshots();
4797     LOGH("E");
4798 
4799     //Set rotation value from user settings as Jpeg rotation
4800     //to configure back-end modules.
4801     mParameters.setJpegRotation(mParameters.getRotation());
4802 
4803     // Check if retro-active snapshots are not enabled
4804     if (!isRetroPicture() || !mParameters.isZSLMode()) {
4805       numRetroSnapshots = 0;
4806       LOGH("Reset retro snaphot count to zero");
4807     }
4808 
4809     //Do special configure for advanced capture modes.
4810     rc = configureAdvancedCapture();
4811     if (rc != NO_ERROR) {
4812         LOGE("Unsupported capture call");
4813         return rc;
4814     }
4815 
4816     if(mActiveCamera == MM_CAMERA_DUAL_CAM) {
4817         /*Need to remove once we have dual camera fusion*/
4818         numSnapshots = numSnapshots/MM_CAMERA_MAX_CAM_CNT;
4819     }
4820 
4821     if (mAdvancedCaptureConfigured) {
4822         numSnapshots = mParameters.getBurstCountForAdvancedCapture();
4823     }
4824     LOGI("snap count = %d zsl = %d advanced = %d",
4825             numSnapshots, mParameters.isZSLMode(), mAdvancedCaptureConfigured);
4826 
4827     if (mParameters.isZSLMode()) {
4828         QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
4829         QCameraPicChannel *pPicChannel = (QCameraPicChannel *)pChannel;
4830         if (NULL != pPicChannel) {
4831 
4832             if (mParameters.getofflineRAW()) {
4833                 startRAWChannel(pPicChannel);
4834                 pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_RAW];
4835                 if (pPicChannel == NULL) {
4836                     LOGE("RAW Channel is NULL in Manual capture mode");
4837                     stopRAWChannel();
4838                     return UNKNOWN_ERROR;
4839                 }
4840             }
4841 
4842             rc = configureOnlineRotation(*pPicChannel);
4843             if (rc != NO_ERROR) {
4844                 LOGE("online rotation failed");
4845                 return rc;
4846             }
4847 
4848             // start postprocessor
4849             DeferWorkArgs args;
4850             memset(&args, 0, sizeof(DeferWorkArgs));
4851 
4852             args.pprocArgs = pPicChannel;
4853 
4854             // No need to wait for mInitPProcJob here, because it was
4855             // queued in startPreview, and will definitely be processed before
4856             // mReprocJob can begin.
4857             mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START,
4858                     args);
4859             if (mReprocJob == 0) {
4860                 LOGE("Failure: Unable to start pproc");
4861                 return -ENOMEM;
4862             }
4863 
4864             // Check if all preview buffers are mapped before creating
4865             // a jpeg session as preview stream buffers are queried during the same
4866             uint8_t numStreams = pChannel->getNumOfStreams();
4867             QCameraStream *pStream = NULL;
4868             QCameraStream *pPreviewStream = NULL;
4869             for (uint8_t i = 0 ; i < numStreams ; i++ ) {
4870                 pStream = pChannel->getStreamByIndex(i);
4871                 if (!pStream)
4872                     continue;
4873                 if (CAM_STREAM_TYPE_PREVIEW == pStream->getMyType()) {
4874                     pPreviewStream = pStream;
4875                     break;
4876                 }
4877             }
4878             if (pPreviewStream != NULL) {
4879                 Mutex::Autolock l(mMapLock);
4880                 QCameraMemory *pMemory = pStream->getStreamBufs();
4881                 if (!pMemory) {
4882                     LOGE("Error!! pMemory is NULL");
4883                     return -ENOMEM;
4884                 }
4885 
4886                 uint8_t waitCnt = 2;
4887                 while (!pMemory->checkIfAllBuffersMapped() && (waitCnt > 0)) {
4888                     LOGL(" Waiting for preview buffers to be mapped");
4889                     mMapCond.waitRelative(
4890                             mMapLock, CAMERA_DEFERRED_MAP_BUF_TIMEOUT);
4891                     LOGL("Wait completed!!");
4892                     waitCnt--;
4893                 }
4894                 // If all buffers are not mapped after retries, assert
4895                 assert(pMemory->checkIfAllBuffersMapped());
4896             } else {
4897                 assert(pPreviewStream);
4898             }
4899 
4900             // Create JPEG session
4901             mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION,
4902                     args);
4903             if (mJpegJob == 0) {
4904                 LOGE("Failed to queue CREATE_JPEG_SESSION");
4905                 if (NO_ERROR != waitDeferredWork(mReprocJob)) {
4906                         LOGE("Reprocess Deferred work was failed");
4907                 }
4908                 m_postprocessor.stop();
4909                 return -ENOMEM;
4910             }
4911 
4912             if (mAdvancedCaptureConfigured) {
4913                 rc = startAdvancedCapture(pPicChannel);
4914                 if (rc != NO_ERROR) {
4915                     LOGE("cannot start zsl advanced capture");
4916                     return rc;
4917                 }
4918             }
4919             if (mLongshotEnabled && mPrepSnapRun) {
4920                 mCameraHandle->ops->start_zsl_snapshot(
4921                         mCameraHandle->camera_handle,
4922                         pPicChannel->getMyHandle());
4923             }
4924             // If frame sync is ON and it is a SECONDARY camera,
4925             // we do not need to send the take picture command to interface
4926             // It will be handled along with PRIMARY camera takePicture request
4927             mm_camera_req_buf_t buf;
4928             memset(&buf, 0x0, sizeof(buf));
4929             if ((!mParameters.isAdvCamFeaturesEnabled() &&
4930                     !mFlashNeeded &&
4931                     !isLongshotEnabled() &&
4932                     isFrameSyncEnabled()) &&
4933                     (getRelatedCamSyncInfo()->sync_control ==
4934                     CAM_SYNC_RELATED_SENSORS_ON)) {
4935                 if (getRelatedCamSyncInfo()->mode == CAM_MODE_PRIMARY) {
4936                     buf.type = MM_CAMERA_REQ_FRAME_SYNC_BUF;
4937                     buf.num_buf_requested = numSnapshots;
4938                     rc = pPicChannel->takePicture(&buf);
4939                     if (rc != NO_ERROR) {
4940                         LOGE("FS_DBG cannot take ZSL picture, stop pproc");
4941                         if (NO_ERROR != waitDeferredWork(mReprocJob)) {
4942                             LOGE("Reprocess Deferred work failed");
4943                             return UNKNOWN_ERROR;
4944                         }
4945                         if (NO_ERROR != waitDeferredWork(mJpegJob)) {
4946                             LOGE("Jpeg Deferred work failed");
4947                             return UNKNOWN_ERROR;
4948                         }
4949                         m_postprocessor.stop();
4950                         return rc;
4951                     }
4952                     LOGI("PRIMARY camera: send frame sync takePicture!!");
4953                 }
4954             } else {
4955                 buf.type = MM_CAMERA_REQ_SUPER_BUF;
4956                 buf.num_buf_requested = numSnapshots;
4957                 buf.num_retro_buf_requested = numRetroSnapshots;
4958                 rc = pPicChannel->takePicture(&buf);
4959                 if (rc != NO_ERROR) {
4960                     LOGE("cannot take ZSL picture, stop pproc");
4961                         if (NO_ERROR != waitDeferredWork(mReprocJob)) {
4962                             LOGE("Reprocess Deferred work failed");
4963                             return UNKNOWN_ERROR;
4964                         }
4965                         if (NO_ERROR != waitDeferredWork(mJpegJob)) {
4966                             LOGE("Jpeg Deferred work failed");
4967                             return UNKNOWN_ERROR;
4968                         }
4969                     m_postprocessor.stop();
4970                     return rc;
4971                 }
4972             }
4973         } else {
4974             LOGE("ZSL channel is NULL");
4975             return UNKNOWN_ERROR;
4976         }
4977     } else {
4978 
4979         // start snapshot
4980         if (mParameters.isJpegPictureFormat() ||
4981                 mParameters.isNV16PictureFormat() ||
4982                 mParameters.isNV21PictureFormat()) {
4983 
4984             //STOP Preview for Non ZSL use case
4985             stopPreview();
4986 
4987             //Config CAPTURE channels
4988             rc = declareSnapshotStreams();
4989             if (NO_ERROR != rc) {
4990                 return rc;
4991             }
4992 
4993             rc = addCaptureChannel();
4994             if ((rc == NO_ERROR) &&
4995                     (NULL != m_channels[QCAMERA_CH_TYPE_CAPTURE])) {
4996 
4997                 if (!mParameters.getofflineRAW()) {
4998                     rc = configureOnlineRotation(
4999                         *m_channels[QCAMERA_CH_TYPE_CAPTURE]);
5000                     if (rc != NO_ERROR) {
5001                         LOGE("online rotation failed");
5002                         delChannel(QCAMERA_CH_TYPE_CAPTURE);
5003                         return rc;
5004                     }
5005                 }
5006 
5007                 DeferWorkArgs args;
5008                 memset(&args, 0, sizeof(DeferWorkArgs));
5009 
5010                 args.pprocArgs = m_channels[QCAMERA_CH_TYPE_CAPTURE];
5011 
5012                 // No need to wait for mInitPProcJob here, because it was
5013                 // queued in startPreview, and will definitely be processed before
5014                 // mReprocJob can begin.
5015                 mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START,
5016                         args);
5017                 if (mReprocJob == 0) {
5018                     LOGE("Failure: Unable to start pproc");
5019                     return -ENOMEM;
5020                 }
5021 
5022                 // Create JPEG session
5023                 mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION,
5024                         args);
5025                 if (mJpegJob == 0) {
5026                     LOGE("Failed to queue CREATE_JPEG_SESSION");
5027                     if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5028                         LOGE("Reprocess Deferred work was failed");
5029                     }
5030                     m_postprocessor.stop();
5031                     return -ENOMEM;
5032                 }
5033 
5034                 // start catpure channel
5035                 rc =  m_channels[QCAMERA_CH_TYPE_CAPTURE]->start();
5036                 if (rc != NO_ERROR) {
5037                     LOGE("cannot start capture channel");
5038                     if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5039                         LOGE("Reprocess Deferred work failed");
5040                         return UNKNOWN_ERROR;
5041                     }
5042                     if (NO_ERROR != waitDeferredWork(mJpegJob)) {
5043                         LOGE("Jpeg Deferred work failed");
5044                         return UNKNOWN_ERROR;
5045                     }
5046                     delChannel(QCAMERA_CH_TYPE_CAPTURE);
5047                     return rc;
5048                 }
5049 
5050                 QCameraPicChannel *pCapChannel =
5051                     (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_CAPTURE];
5052                 if (NULL != pCapChannel) {
5053                     if (mParameters.isUbiFocusEnabled() ||
5054                             mParameters.isUbiRefocus() ||
5055                             mParameters.isChromaFlashEnabled()) {
5056                         rc = startAdvancedCapture(pCapChannel);
5057                         if (rc != NO_ERROR) {
5058                             LOGE("cannot start advanced capture");
5059                             return rc;
5060                         }
5061                     }
5062                 }
5063                 if ( mLongshotEnabled ) {
5064                     rc = longShot();
5065                     if (NO_ERROR != rc) {
5066                         if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5067                             LOGE("Reprocess Deferred work failed");
5068                             return UNKNOWN_ERROR;
5069                         }
5070                         if (NO_ERROR != waitDeferredWork(mJpegJob)) {
5071                             LOGE("Jpeg Deferred work failed");
5072                             return UNKNOWN_ERROR;
5073                         }
5074                         delChannel(QCAMERA_CH_TYPE_CAPTURE);
5075                         return rc;
5076                     }
5077                 }
5078             } else {
5079                 LOGE("cannot add capture channel");
5080                 delChannel(QCAMERA_CH_TYPE_CAPTURE);
5081                 return rc;
5082             }
5083         } else {
5084             // Stop Preview before taking NZSL snapshot
5085             stopPreview();
5086 
5087             rc = mParameters.updateRAW(gCamCapability[mCameraId]->raw_dim[0]);
5088             if (NO_ERROR != rc) {
5089                 LOGE("Raw dimension update failed %d", rc);
5090                 return rc;
5091             }
5092 
5093             rc = declareSnapshotStreams();
5094             if (NO_ERROR != rc) {
5095                 LOGE("RAW stream info configuration failed %d", rc);
5096                 return rc;
5097             }
5098 
5099             rc = addChannel(QCAMERA_CH_TYPE_RAW);
5100             if (rc == NO_ERROR) {
5101                 // start postprocessor
5102                 if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
5103                     LOGE("Reprocess Deferred work failed");
5104                     return UNKNOWN_ERROR;
5105                 }
5106 
5107                 rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]);
5108                 if (rc != NO_ERROR) {
5109                     LOGE("cannot start postprocessor");
5110                     delChannel(QCAMERA_CH_TYPE_RAW);
5111                     return rc;
5112                 }
5113 
5114                 rc = startChannel(QCAMERA_CH_TYPE_RAW);
5115                 if (rc != NO_ERROR) {
5116                     LOGE("cannot start raw channel");
5117                     m_postprocessor.stop();
5118                     delChannel(QCAMERA_CH_TYPE_RAW);
5119                     return rc;
5120                 }
5121             } else {
5122                 LOGE("cannot add raw channel");
5123                 return rc;
5124             }
5125         }
5126     }
5127 
5128     //When take picture, stop sending preview callbacks to APP
5129     m_stateMachine.setPreviewCallbackNeeded(false);
5130     LOGI("X rc = %d", rc);
5131     return rc;
5132 }
5133 
5134 /*===========================================================================
5135  * FUNCTION   : configureOnlineRotation
5136  *
5137  * DESCRIPTION: Configure backend with expected rotation for snapshot stream
5138  *
5139  * PARAMETERS :
5140  *    @ch     : Channel containing a snapshot stream
5141  *
5142  * RETURN     : int32_t type of status
5143  *              NO_ERROR  -- success
5144  *              none-zero failure code
5145  *==========================================================================*/
configureOnlineRotation(QCameraChannel & ch)5146 int32_t QCamera2HardwareInterface::configureOnlineRotation(QCameraChannel &ch)
5147 {
5148     int rc = NO_ERROR;
5149     uint32_t streamId = 0;
5150     QCameraStream *pStream = NULL;
5151 
5152     for (uint8_t i = 0; i < ch.getNumOfStreams(); i++) {
5153         QCameraStream *stream = ch.getStreamByIndex(i);
5154         if ((NULL != stream) &&
5155                 ((CAM_STREAM_TYPE_SNAPSHOT == stream->getMyType())
5156                 || (CAM_STREAM_TYPE_RAW == stream->getMyType()))) {
5157             pStream = stream;
5158             break;
5159         }
5160     }
5161 
5162     if (NULL == pStream) {
5163         LOGE("No snapshot stream found!");
5164         return BAD_VALUE;
5165     }
5166 
5167     streamId = pStream->getMyServerID();
5168     // Update online rotation configuration
5169     rc = mParameters.addOnlineRotation(mParameters.getJpegRotation(), streamId,
5170             mParameters.getDeviceRotation());
5171     if (rc != NO_ERROR) {
5172         LOGE("addOnlineRotation failed %d", rc);
5173         return rc;
5174     }
5175 
5176     return rc;
5177 }
5178 
5179 /*===========================================================================
5180  * FUNCTION   : declareSnapshotStreams
5181  *
5182  * DESCRIPTION: Configure backend with expected snapshot streams
5183  *
5184  * PARAMETERS : none
5185  *
5186  * RETURN     : int32_t type of status
5187  *              NO_ERROR  -- success
5188  *              none-zero failure code
5189  *==========================================================================*/
declareSnapshotStreams()5190 int32_t QCamera2HardwareInterface::declareSnapshotStreams()
5191 {
5192     int rc = NO_ERROR;
5193 
5194     // Update stream info configuration
5195     rc = mParameters.setStreamConfigure(true, mLongshotEnabled, false);
5196     if (rc != NO_ERROR) {
5197         LOGE("setStreamConfigure failed %d", rc);
5198         return rc;
5199     }
5200 
5201     return rc;
5202 }
5203 
5204 /*===========================================================================
5205  * FUNCTION   : longShot
5206  *
5207  * DESCRIPTION: Queue one more ZSL frame
5208  *              in the longshot pipe.
5209  *
5210  * PARAMETERS : none
5211  *
5212  * RETURN     : int32_t type of status
5213  *              NO_ERROR  -- success
5214  *              none-zero failure code
5215  *==========================================================================*/
longShot()5216 int32_t QCamera2HardwareInterface::longShot()
5217 {
5218     int32_t rc = NO_ERROR;
5219     uint8_t numSnapshots = mParameters.getNumOfSnapshots();
5220     QCameraPicChannel *pChannel = NULL;
5221 
5222     if (mParameters.isZSLMode()) {
5223         pChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
5224     } else {
5225         pChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_CAPTURE];
5226     }
5227 
5228     if (NULL != pChannel) {
5229         mm_camera_req_buf_t buf;
5230         memset(&buf, 0x0, sizeof(buf));
5231         buf.type = MM_CAMERA_REQ_SUPER_BUF;
5232         buf.num_buf_requested = numSnapshots;
5233         rc = pChannel->takePicture(&buf);
5234     } else {
5235         LOGE("Capture channel not initialized!");
5236         rc = NO_INIT;
5237         goto end;
5238     }
5239 
5240 end:
5241     return rc;
5242 }
5243 
5244 /*===========================================================================
5245  * FUNCTION   : stopCaptureChannel
5246  *
5247  * DESCRIPTION: Stops capture channel
5248  *
5249  * PARAMETERS :
5250  *   @destroy : Set to true to stop and delete camera channel.
5251  *              Set to false to only stop capture channel.
5252  *
5253  * RETURN     : int32_t type of status
5254  *              NO_ERROR  -- success
5255  *              none-zero failure code
5256  *==========================================================================*/
stopCaptureChannel(bool destroy)5257 int QCamera2HardwareInterface::stopCaptureChannel(bool destroy)
5258 {
5259     int rc = NO_ERROR;
5260     if (mParameters.isJpegPictureFormat() ||
5261         mParameters.isNV16PictureFormat() ||
5262         mParameters.isNV21PictureFormat()) {
5263         mParameters.setQuadraCfaMode(false, true);
5264         rc = stopChannel(QCAMERA_CH_TYPE_CAPTURE);
5265         if (destroy && (NO_ERROR == rc)) {
5266             // Destroy camera channel but dont release context
5267             waitDeferredWork(mJpegJob);
5268             rc = delChannel(QCAMERA_CH_TYPE_CAPTURE, false);
5269         }
5270     }
5271 
5272     return rc;
5273 }
5274 
5275 /*===========================================================================
5276  * FUNCTION   : cancelPicture
5277  *
5278  * DESCRIPTION: cancel picture impl
5279  *
5280  * PARAMETERS : none
5281  *
5282  * RETURN     : int32_t type of status
5283  *              NO_ERROR  -- success
5284  *              none-zero failure code
5285  *==========================================================================*/
cancelPicture()5286 int QCamera2HardwareInterface::cancelPicture()
5287 {
5288     waitDeferredWork(mReprocJob);
5289     waitDeferredWork(mJpegJob);
5290 
5291     //stop post processor
5292     m_postprocessor.stop();
5293 
5294     unconfigureAdvancedCapture();
5295     LOGH("Enable display frames again");
5296     setDisplaySkip(FALSE);
5297 
5298     if (mParameters.isZSLMode()) {
5299         QCameraPicChannel *pPicChannel = NULL;
5300         if (mParameters.getofflineRAW()) {
5301             pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_RAW];
5302         } else {
5303             pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
5304         }
5305         if (NULL != pPicChannel) {
5306             pPicChannel->cancelPicture();
5307             stopRAWChannel();
5308             stopAdvancedCapture(pPicChannel);
5309         }
5310     } else {
5311 
5312         // normal capture case
5313         if (mParameters.isJpegPictureFormat() ||
5314             mParameters.isNV16PictureFormat() ||
5315             mParameters.isNV21PictureFormat()) {
5316             stopChannel(QCAMERA_CH_TYPE_CAPTURE);
5317             delChannel(QCAMERA_CH_TYPE_CAPTURE);
5318         } else {
5319             stopChannel(QCAMERA_CH_TYPE_RAW);
5320             delChannel(QCAMERA_CH_TYPE_RAW);
5321         }
5322     }
5323 
5324     return NO_ERROR;
5325 }
5326 
5327 /*===========================================================================
5328  * FUNCTION   : captureDone
5329  *
5330  * DESCRIPTION: Function called when the capture is completed before encoding
5331  *
5332  * PARAMETERS : none
5333  *
5334  * RETURN     : none
5335  *==========================================================================*/
captureDone()5336 void QCamera2HardwareInterface::captureDone()
5337 {
5338     qcamera_sm_internal_evt_payload_t *payload =
5339        (qcamera_sm_internal_evt_payload_t *)
5340        malloc(sizeof(qcamera_sm_internal_evt_payload_t));
5341     if (NULL != payload) {
5342         memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
5343         payload->evt_type = QCAMERA_INTERNAL_EVT_ZSL_CAPTURE_DONE;
5344         int32_t rc = processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
5345         if (rc != NO_ERROR) {
5346             LOGE("processEvt ZSL capture done failed");
5347             free(payload);
5348             payload = NULL;
5349         }
5350     } else {
5351         LOGE("No memory for ZSL capture done event");
5352     }
5353 }
5354 
5355 /*===========================================================================
5356  * FUNCTION   : Live_Snapshot_thread
5357  *
5358  * DESCRIPTION: Seperate thread for taking live snapshot during recording
5359  *
5360  * PARAMETERS : @data - pointer to QCamera2HardwareInterface class object
5361  *
5362  * RETURN     : none
5363  *==========================================================================*/
Live_Snapshot_thread(void * data)5364 void* Live_Snapshot_thread (void* data)
5365 {
5366 
5367     QCamera2HardwareInterface *hw = reinterpret_cast<QCamera2HardwareInterface *>(data);
5368     if (!hw) {
5369         LOGE("take_picture_thread: NULL camera device");
5370         return (void *)BAD_VALUE;
5371     }
5372     if (hw->bLiveSnapshot) {
5373         hw->takeLiveSnapshot_internal();
5374     } else {
5375         hw->cancelLiveSnapshot_internal();
5376     }
5377     return (void* )NULL;
5378 }
5379 
5380 /*===========================================================================
5381  * FUNCTION   : Int_Pic_thread
5382  *
5383  * DESCRIPTION: Seperate thread for taking snapshot triggered by camera backend
5384  *
5385  * PARAMETERS : @data - pointer to QCamera2HardwareInterface class object
5386  *
5387  * RETURN     : none
5388  *==========================================================================*/
Int_Pic_thread(void * data)5389 void* Int_Pic_thread (void* data)
5390 {
5391     int rc = NO_ERROR;
5392 
5393     QCamera2HardwareInterface *hw = reinterpret_cast<QCamera2HardwareInterface *>(data);
5394 
5395     if (!hw) {
5396         LOGE("take_picture_thread: NULL camera device");
5397         return (void *)BAD_VALUE;
5398     }
5399 
5400     bool JpegMemOpt = false;
5401     char raw_format[PROPERTY_VALUE_MAX];
5402 
5403     memset(raw_format, 0, sizeof(raw_format));
5404 
5405     rc = hw->takeBackendPic_internal(&JpegMemOpt, &raw_format[0]);
5406     if (rc == NO_ERROR) {
5407         hw->checkIntPicPending(JpegMemOpt, &raw_format[0]);
5408     } else {
5409         //Snapshot attempt not successful, we need to do cleanup here
5410         hw->clearIntPendingEvents();
5411     }
5412 
5413     return (void* )NULL;
5414 }
5415 
5416 /*===========================================================================
5417  * FUNCTION   : takeLiveSnapshot
5418  *
5419  * DESCRIPTION: take live snapshot during recording
5420  *
5421  * PARAMETERS : none
5422  *
5423  * RETURN     : int32_t type of status
5424  *              NO_ERROR  -- success
5425  *              none-zero failure code
5426  *==========================================================================*/
takeLiveSnapshot()5427 int QCamera2HardwareInterface::takeLiveSnapshot()
5428 {
5429     int rc = NO_ERROR;
5430     if (mLiveSnapshotThread != 0) {
5431         pthread_join(mLiveSnapshotThread,NULL);
5432         mLiveSnapshotThread = 0;
5433     }
5434     bLiveSnapshot = true;
5435     rc= pthread_create(&mLiveSnapshotThread, NULL, Live_Snapshot_thread, (void *) this);
5436     if (!rc) {
5437         pthread_setname_np(mLiveSnapshotThread, "CAM_liveSnap");
5438     }
5439     return rc;
5440 }
5441 
5442 /*===========================================================================
5443  * FUNCTION   : takePictureInternal
5444  *
5445  * DESCRIPTION: take snapshot triggered by backend
5446  *
5447  * PARAMETERS : none
5448  *
5449  * RETURN     : int32_t type of status
5450  *              NO_ERROR  -- success
5451  *              none-zero failure code
5452  *==========================================================================*/
takePictureInternal()5453 int QCamera2HardwareInterface::takePictureInternal()
5454 {
5455     int rc = NO_ERROR;
5456     rc= pthread_create(&mIntPicThread, NULL, Int_Pic_thread, (void *) this);
5457     if (!rc) {
5458         pthread_setname_np(mIntPicThread, "CAM_IntPic");
5459     }
5460     return rc;
5461 }
5462 
5463 /*===========================================================================
5464  * FUNCTION   : checkIntPicPending
5465  *
5466  * DESCRIPTION: timed wait for jpeg completion event, and send
5467  *                        back completion event to backend
5468  *
5469  * PARAMETERS : none
5470  *
5471  * RETURN     : none
5472  *==========================================================================*/
checkIntPicPending(bool JpegMemOpt,char * raw_format)5473 void QCamera2HardwareInterface::checkIntPicPending(bool JpegMemOpt, char *raw_format)
5474 {
5475     bool bSendToBackend = true;
5476     cam_int_evt_params_t params;
5477     int rc = NO_ERROR;
5478 
5479     struct timespec   ts;
5480     struct timeval    tp;
5481     gettimeofday(&tp, NULL);
5482     ts.tv_sec  = tp.tv_sec + 5;
5483     ts.tv_nsec = tp.tv_usec * 1000;
5484 
5485     if (true == m_bIntJpegEvtPending ||
5486         (true == m_bIntRawEvtPending)) {
5487         //Waiting in HAL for snapshot taken notification
5488         pthread_mutex_lock(&m_int_lock);
5489         rc = pthread_cond_timedwait(&m_int_cond, &m_int_lock, &ts);
5490         if (ETIMEDOUT == rc || 0x0 == m_BackendFileName[0]) {
5491             //Hit a timeout, or some spurious activity
5492             bSendToBackend = false;
5493         }
5494 
5495         if (true == m_bIntJpegEvtPending) {
5496             params.event_type = 0;
5497             mParameters.getStreamFormat(CAM_STREAM_TYPE_SNAPSHOT, params.picture_format);
5498         } else if (true == m_bIntRawEvtPending) {
5499             params.event_type = 1;
5500             mParameters.getStreamFormat(CAM_STREAM_TYPE_RAW, params.picture_format);
5501         }
5502         pthread_mutex_unlock(&m_int_lock);
5503 
5504         if (true == m_bIntJpegEvtPending) {
5505             //Attempting to restart preview after taking JPEG snapshot
5506             lockAPI();
5507             rc = processAPI(QCAMERA_SM_EVT_SNAPSHOT_DONE, NULL);
5508             unlockAPI();
5509             m_postprocessor.setJpegMemOpt(JpegMemOpt);
5510         } else if (true == m_bIntRawEvtPending) {
5511             //Attempting to restart preview after taking RAW snapshot
5512             stopChannel(QCAMERA_CH_TYPE_RAW);
5513             delChannel(QCAMERA_CH_TYPE_RAW);
5514             //restoring the old raw format
5515             property_set("persist.camera.raw.format", raw_format);
5516         }
5517 
5518         if (true == bSendToBackend) {
5519             //send event back to server with the file path
5520             params.dim = m_postprocessor.m_dst_dim;
5521             memcpy(&params.path[0], &m_BackendFileName[0], QCAMERA_MAX_FILEPATH_LENGTH);
5522             memset(&m_BackendFileName[0], 0x0, QCAMERA_MAX_FILEPATH_LENGTH);
5523             params.size = mBackendFileSize;
5524             rc = mParameters.setIntEvent(params);
5525         }
5526 
5527         clearIntPendingEvents();
5528     }
5529 
5530     return;
5531 }
5532 
5533 /*===========================================================================
5534  * FUNCTION   : takeBackendPic_internal
5535  *
5536  * DESCRIPTION: take snapshot triggered by backend
5537  *
5538  * PARAMETERS : none
5539  *
5540  * RETURN     : int32_t type of status
5541  *              NO_ERROR  -- success
5542  *              none-zero failure code
5543  *==========================================================================*/
takeBackendPic_internal(bool * JpegMemOpt,char * raw_format)5544 int QCamera2HardwareInterface::takeBackendPic_internal(bool *JpegMemOpt, char *raw_format)
5545 {
5546     int rc = NO_ERROR;
5547     qcamera_api_result_t apiResult;
5548 
5549     lockAPI();
5550     //Set rotation value from user settings as Jpeg rotation
5551     //to configure back-end modules.
5552     mParameters.setJpegRotation(mParameters.getRotation());
5553 
5554     setRetroPicture(0);
5555     /* Prepare snapshot in case LED needs to be flashed */
5556     if (mFlashNeeded == 1 || mParameters.isChromaFlashEnabled()) {
5557         // Start Preparing for normal Frames
5558         LOGH("Start Prepare Snapshot");
5559         /* Prepare snapshot in case LED needs to be flashed */
5560         rc = processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL);
5561         if (rc == NO_ERROR) {
5562             waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, &apiResult);
5563             rc = apiResult.status;
5564         }
5565         LOGH("Prep Snapshot done rc = %d", rc);
5566         mPrepSnapRun = true;
5567     }
5568     unlockAPI();
5569 
5570     if (true == m_bIntJpegEvtPending) {
5571         //Attempting to take JPEG snapshot
5572         if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
5573             LOGE("Init PProc Deferred work failed");
5574             return UNKNOWN_ERROR;
5575         }
5576         *JpegMemOpt = m_postprocessor.getJpegMemOpt();
5577         m_postprocessor.setJpegMemOpt(false);
5578 
5579         /* capture */
5580         lockAPI();
5581         LOGH("Capturing internal snapshot");
5582         rc = processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL);
5583         if (rc == NO_ERROR) {
5584             waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult);
5585             rc = apiResult.status;
5586         }
5587         unlockAPI();
5588     } else if (true == m_bIntRawEvtPending) {
5589         //Attempting to take RAW snapshot
5590         (void)JpegMemOpt;
5591         stopPreview();
5592 
5593         //getting the existing raw format type
5594         property_get("persist.camera.raw.format", raw_format, "17");
5595         //setting it to a default know value for this task
5596         property_set("persist.camera.raw.format", "18");
5597 
5598         rc = addChannel(QCAMERA_CH_TYPE_RAW);
5599         if (rc == NO_ERROR) {
5600             // start postprocessor
5601             if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
5602                 LOGE("Init PProc Deferred work failed");
5603                 return UNKNOWN_ERROR;
5604             }
5605             rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]);
5606             if (rc != NO_ERROR) {
5607                 LOGE("cannot start postprocessor");
5608                 delChannel(QCAMERA_CH_TYPE_RAW);
5609                 return rc;
5610             }
5611 
5612             rc = startChannel(QCAMERA_CH_TYPE_RAW);
5613             if (rc != NO_ERROR) {
5614                 LOGE("cannot start raw channel");
5615                 m_postprocessor.stop();
5616                 delChannel(QCAMERA_CH_TYPE_RAW);
5617                 return rc;
5618             }
5619         } else {
5620             LOGE("cannot add raw channel");
5621             return rc;
5622         }
5623     }
5624 
5625     return rc;
5626 }
5627 
5628 /*===========================================================================
5629  * FUNCTION   : clearIntPendingEvents
5630  *
5631  * DESCRIPTION: clear internal pending events pertaining to backend
5632  *                        snapshot requests
5633  *
5634  * PARAMETERS : none
5635  *
5636  * RETURN     : int32_t type of status
5637  *              NO_ERROR  -- success
5638  *              none-zero failure code
5639  *==========================================================================*/
clearIntPendingEvents()5640 void QCamera2HardwareInterface::clearIntPendingEvents()
5641 {
5642     int rc = NO_ERROR;
5643 
5644     if (true == m_bIntRawEvtPending) {
5645         preparePreview();
5646         startPreview();
5647     }
5648     if (true == m_bIntJpegEvtPending) {
5649         if (false == mParameters.isZSLMode()) {
5650             lockAPI();
5651             rc = processAPI(QCAMERA_SM_EVT_START_PREVIEW, NULL);
5652             unlockAPI();
5653         }
5654     }
5655 
5656     pthread_mutex_lock(&m_int_lock);
5657     if (true == m_bIntJpegEvtPending) {
5658         m_bIntJpegEvtPending = false;
5659     } else if (true == m_bIntRawEvtPending) {
5660         m_bIntRawEvtPending = false;
5661     }
5662     pthread_mutex_unlock(&m_int_lock);
5663     return;
5664 }
5665 
5666 /*===========================================================================
5667  * FUNCTION   : takeLiveSnapshot_internal
5668  *
5669  * DESCRIPTION: take live snapshot during recording
5670  *
5671  * PARAMETERS : none
5672  *
5673  * RETURN     : int32_t type of status
5674  *              NO_ERROR  -- success
5675  *              none-zero failure code
5676  *==========================================================================*/
takeLiveSnapshot_internal()5677 int QCamera2HardwareInterface::takeLiveSnapshot_internal()
5678 {
5679     int rc = NO_ERROR;
5680 
5681     QCameraChannel *pChannel = NULL;
5682     QCameraChannel *pPreviewChannel = NULL;
5683     QCameraStream  *pPreviewStream = NULL;
5684     QCameraStream  *pStream = NULL;
5685 
5686     //Set rotation value from user settings as Jpeg rotation
5687     //to configure back-end modules.
5688     mParameters.setJpegRotation(mParameters.getRotation());
5689 
5690     // Configure advanced capture
5691     rc = configureAdvancedCapture();
5692     if (rc != NO_ERROR) {
5693         LOGE("Unsupported capture call");
5694         goto end;
5695     }
5696 
5697     if (isLowPowerMode()) {
5698         pChannel = m_channels[QCAMERA_CH_TYPE_VIDEO];
5699     } else {
5700         pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
5701     }
5702 
5703     if (NULL == pChannel) {
5704         LOGE("Snapshot/Video channel not initialized");
5705         rc = NO_INIT;
5706         goto end;
5707     }
5708 
5709     // Check if all preview buffers are mapped before creating
5710     // a jpeg session as preview stream buffers are queried during the same
5711     pPreviewChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
5712     if (pPreviewChannel != NULL) {
5713         uint32_t numStreams = pPreviewChannel->getNumOfStreams();
5714 
5715         for (uint8_t i = 0 ; i < numStreams ; i++ ) {
5716             pStream = pPreviewChannel->getStreamByIndex(i);
5717             if (!pStream)
5718                 continue;
5719             if (CAM_STREAM_TYPE_PREVIEW == pStream->getMyType()) {
5720                 pPreviewStream = pStream;
5721                 break;
5722             }
5723         }
5724 
5725         if (pPreviewStream != NULL) {
5726             Mutex::Autolock l(mMapLock);
5727             QCameraMemory *pMemory = pStream->getStreamBufs();
5728             if (!pMemory) {
5729                 LOGE("Error!! pMemory is NULL");
5730                 return -ENOMEM;
5731             }
5732 
5733             uint8_t waitCnt = 2;
5734             while (!pMemory->checkIfAllBuffersMapped() && (waitCnt > 0)) {
5735                 LOGL(" Waiting for preview buffers to be mapped");
5736                 mMapCond.waitRelative(
5737                         mMapLock, CAMERA_DEFERRED_MAP_BUF_TIMEOUT);
5738                 LOGL("Wait completed!!");
5739                 waitCnt--;
5740             }
5741             // If all buffers are not mapped after retries, assert
5742             assert(pMemory->checkIfAllBuffersMapped());
5743         } else {
5744             assert(pPreviewStream);
5745         }
5746     }
5747 
5748     DeferWorkArgs args;
5749     memset(&args, 0, sizeof(DeferWorkArgs));
5750 
5751     args.pprocArgs = pChannel;
5752 
5753     // No need to wait for mInitPProcJob here, because it was
5754     // queued in startPreview, and will definitely be processed before
5755     // mReprocJob can begin.
5756     mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START,
5757             args);
5758     if (mReprocJob == 0) {
5759         LOGE("Failed to queue CMD_DEF_PPROC_START");
5760         rc = -ENOMEM;
5761         goto end;
5762     }
5763 
5764     // Create JPEG session
5765     mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION,
5766             args);
5767     if (mJpegJob == 0) {
5768         LOGE("Failed to queue CREATE_JPEG_SESSION");
5769         if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5770             LOGE("Reprocess Deferred work was failed");
5771         }
5772         m_postprocessor.stop();
5773         rc = -ENOMEM;
5774         goto end;
5775     }
5776 
5777     if (isLowPowerMode()) {
5778         mm_camera_req_buf_t buf;
5779         memset(&buf, 0x0, sizeof(buf));
5780         buf.type = MM_CAMERA_REQ_SUPER_BUF;
5781         buf.num_buf_requested = 1;
5782         rc = ((QCameraVideoChannel*)pChannel)->takePicture(&buf);
5783         goto end;
5784     }
5785 
5786     //Disable reprocess for 4K liveshot case
5787     if (!mParameters.is4k2kVideoResolution()) {
5788         rc = configureOnlineRotation(*m_channels[QCAMERA_CH_TYPE_SNAPSHOT]);
5789         if (rc != NO_ERROR) {
5790             LOGE("online rotation failed");
5791             if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5792                 LOGE("Reprocess Deferred work was failed");
5793             }
5794             if (NO_ERROR != waitDeferredWork(mJpegJob)) {
5795                 LOGE("Jpeg Deferred work was failed");
5796             }
5797             m_postprocessor.stop();
5798             return rc;
5799         }
5800     }
5801 
5802     if ((NULL != pChannel) && (mParameters.isTNRSnapshotEnabled())) {
5803         QCameraStream *pStream = NULL;
5804         for (uint32_t i = 0 ; i < pChannel->getNumOfStreams(); i++ ) {
5805             pStream = pChannel->getStreamByIndex(i);
5806             if ((NULL != pStream) &&
5807                     (CAM_STREAM_TYPE_SNAPSHOT == pStream->getMyType())) {
5808                 break;
5809             }
5810         }
5811         if (pStream != NULL) {
5812             LOGD("REQUEST_FRAMES event for TNR snapshot");
5813             cam_stream_parm_buffer_t param;
5814             memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
5815             param.type = CAM_STREAM_PARAM_TYPE_REQUEST_FRAMES;
5816             param.frameRequest.enableStream = 1;
5817             rc = pStream->setParameter(param);
5818             if (rc != NO_ERROR) {
5819                 LOGE("Stream Event REQUEST_FRAMES failed");
5820             }
5821             goto end;
5822         }
5823     }
5824 
5825     // start snapshot channel
5826     if ((rc == NO_ERROR) && (NULL != pChannel)) {
5827         // Do not link metadata stream for 4K2k resolution
5828         // as CPP processing would be done on snapshot stream and not
5829         // reprocess stream
5830         if (!mParameters.is4k2kVideoResolution()) {
5831             // Find and try to link a metadata stream from preview channel
5832             QCameraChannel *pMetaChannel = NULL;
5833             QCameraStream *pMetaStream = NULL;
5834             QCameraStream *pPreviewStream = NULL;
5835 
5836             if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
5837                 pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
5838                 uint32_t streamNum = pMetaChannel->getNumOfStreams();
5839                 QCameraStream *pStream = NULL;
5840                 for (uint32_t i = 0 ; i < streamNum ; i++ ) {
5841                     pStream = pMetaChannel->getStreamByIndex(i);
5842                     if (NULL != pStream) {
5843                         if (CAM_STREAM_TYPE_METADATA == pStream->getMyType()) {
5844                             pMetaStream = pStream;
5845                         } else if ((CAM_STREAM_TYPE_PREVIEW == pStream->getMyType())
5846                                 && (!mParameters.isHfrMode())) {
5847                             // Do not link preview stream for HFR live snapshot.
5848                             // Thumbnail will not be derived from preview for HFR live snapshot.
5849                             pPreviewStream = pStream;
5850                         }
5851                     }
5852                 }
5853             }
5854 
5855             if ((NULL != pMetaChannel) && (NULL != pMetaStream)) {
5856                 rc = pChannel->linkStream(pMetaChannel, pMetaStream);
5857                 if (NO_ERROR != rc) {
5858                     LOGE("Metadata stream link failed %d", rc);
5859                 }
5860             }
5861             if ((NULL != pMetaChannel) && (NULL != pPreviewStream)) {
5862                 rc = pChannel->linkStream(pMetaChannel, pPreviewStream);
5863                 if (NO_ERROR != rc) {
5864                     LOGE("Preview stream link failed %d", rc);
5865                 }
5866             }
5867         }
5868         rc = pChannel->start();
5869     }
5870 
5871 end:
5872     if (rc != NO_ERROR) {
5873         rc = processAPI(QCAMERA_SM_EVT_CANCEL_PICTURE, NULL);
5874         rc = sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
5875     }
5876     return rc;
5877 }
5878 
5879 /*===========================================================================
5880  * FUNCTION   : cancelLiveSnapshot
5881  *
5882  * DESCRIPTION: cancel current live snapshot request
5883  *
5884  * PARAMETERS : none
5885  *
5886  * RETURN     : int32_t type of status
5887  *              NO_ERROR  -- success
5888  *              none-zero failure code
5889  *==========================================================================*/
cancelLiveSnapshot()5890 int QCamera2HardwareInterface::cancelLiveSnapshot()
5891 {
5892     int rc = NO_ERROR;
5893     if (mLiveSnapshotThread != 0) {
5894         pthread_join(mLiveSnapshotThread,NULL);
5895         mLiveSnapshotThread = 0;
5896     }
5897     bLiveSnapshot = false;
5898     rc= pthread_create(&mLiveSnapshotThread, NULL, Live_Snapshot_thread, (void *) this);
5899     if (!rc) {
5900         pthread_setname_np(mLiveSnapshotThread, "CAM_cancel_liveSnap");
5901     }
5902     return rc;
5903 }
5904 
5905 /*===========================================================================
5906  * FUNCTION   : cancelLiveSnapshot_internal
5907  *
5908  * DESCRIPTION: cancel live snapshot during recording
5909  *
5910  * PARAMETERS : none
5911  *
5912  * RETURN     : int32_t type of status
5913  *              NO_ERROR  -- success
5914  *              none-zero failure code
5915  *==========================================================================*/
cancelLiveSnapshot_internal()5916 int QCamera2HardwareInterface::cancelLiveSnapshot_internal() {
5917     int rc = NO_ERROR;
5918 
5919     unconfigureAdvancedCapture();
5920     LOGH("Enable display frames again");
5921     setDisplaySkip(FALSE);
5922 
5923     //stop post processor
5924     m_postprocessor.stop();
5925 
5926     // stop snapshot channel
5927     if (!mParameters.isTNRSnapshotEnabled()) {
5928         rc = stopChannel(QCAMERA_CH_TYPE_SNAPSHOT);
5929     } else {
5930         QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
5931         if (NULL != pChannel) {
5932             QCameraStream *pStream = NULL;
5933             for (uint32_t i = 0 ; i < pChannel->getNumOfStreams(); i++ ) {
5934                 pStream = pChannel->getStreamByIndex(i);
5935                 if ((NULL != pStream) &&
5936                         (CAM_STREAM_TYPE_SNAPSHOT ==
5937                         pStream->getMyType())) {
5938                     break;
5939                 }
5940             }
5941             if (pStream != NULL) {
5942                 LOGD("REQUEST_FRAMES event for TNR snapshot");
5943                 cam_stream_parm_buffer_t param;
5944                 memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
5945                 param.type = CAM_STREAM_PARAM_TYPE_REQUEST_FRAMES;
5946                 param.frameRequest.enableStream = 0;
5947                 rc = pStream->setParameter(param);
5948                 if (rc != NO_ERROR) {
5949                     LOGE("Stream Event REQUEST_FRAMES failed");
5950                 }
5951             }
5952         }
5953     }
5954 
5955     return rc;
5956 }
5957 
5958 /*===========================================================================
5959  * FUNCTION   : putParameters
5960  *
5961  * DESCRIPTION: put parameters string impl
5962  *
5963  * PARAMETERS :
5964  *   @parms   : parameters string to be released
5965  *
5966  * RETURN     : int32_t type of status
5967  *              NO_ERROR  -- success
5968  *              none-zero failure code
5969  *==========================================================================*/
putParameters(char * parms)5970 int QCamera2HardwareInterface::putParameters(char *parms)
5971 {
5972     free(parms);
5973     return NO_ERROR;
5974 }
5975 
5976 /*===========================================================================
5977  * FUNCTION   : sendCommand
5978  *
5979  * DESCRIPTION: send command impl
5980  *
5981  * PARAMETERS :
5982  *   @command : command to be executed
5983  *   @arg1    : optional argument 1
5984  *   @arg2    : optional argument 2
5985  *
5986  * RETURN     : int32_t type of status
5987  *              NO_ERROR  -- success
5988  *              none-zero failure code
5989  *==========================================================================*/
sendCommand(int32_t command,__unused int32_t & arg1,__unused int32_t & arg2)5990 int QCamera2HardwareInterface::sendCommand(int32_t command,
5991         __unused int32_t &arg1, __unused int32_t &arg2)
5992 {
5993     int rc = NO_ERROR;
5994 
5995     switch (command) {
5996 #ifndef VANILLA_HAL
5997     case CAMERA_CMD_LONGSHOT_ON:
5998         arg1 = arg2 = 0;
5999         // Longshot can only be enabled when image capture
6000         // is not active.
6001         if ( !m_stateMachine.isCaptureRunning() ) {
6002             LOGI("Longshot Enabled");
6003             mLongshotEnabled = true;
6004             rc = mParameters.setLongshotEnable(mLongshotEnabled);
6005 
6006             // Due to recent buffer count optimizations
6007             // ZSL might run with considerably less buffers
6008             // when not in longshot mode. Preview needs to
6009             // restart in this case.
6010             if (isZSLMode() && m_stateMachine.isPreviewRunning()) {
6011                 QCameraChannel *pChannel = NULL;
6012                 QCameraStream *pSnapStream = NULL;
6013                 pChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
6014                 if (NULL != pChannel) {
6015                     QCameraStream *pStream = NULL;
6016                     for (uint32_t i = 0; i < pChannel->getNumOfStreams(); i++) {
6017                         pStream = pChannel->getStreamByIndex(i);
6018                         if (pStream != NULL) {
6019                             if (pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT)) {
6020                                 pSnapStream = pStream;
6021                                 break;
6022                             }
6023                         }
6024                     }
6025                     if (NULL != pSnapStream) {
6026                         uint8_t required = 0;
6027                         required = getBufNumRequired(CAM_STREAM_TYPE_SNAPSHOT);
6028                         if (pSnapStream->getBufferCount() < required) {
6029                             // We restart here, to reset the FPS and no
6030                             // of buffers as per the requirement of longshot usecase.
6031                             arg1 = QCAMERA_SM_EVT_RESTART_PERVIEW;
6032                             if (getRelatedCamSyncInfo()->sync_control ==
6033                                     CAM_SYNC_RELATED_SENSORS_ON) {
6034                                 arg2 = QCAMERA_SM_EVT_DELAYED_RESTART;
6035                             }
6036                         }
6037                     }
6038                 }
6039             }
6040             //
6041             mPrepSnapRun = false;
6042             mCACDoneReceived = FALSE;
6043         } else {
6044             rc = NO_INIT;
6045         }
6046         break;
6047     case CAMERA_CMD_LONGSHOT_OFF:
6048         if ( mLongshotEnabled && m_stateMachine.isCaptureRunning() ) {
6049             cancelPicture();
6050             processEvt(QCAMERA_SM_EVT_SNAPSHOT_DONE, NULL);
6051             QCameraChannel *pZSLChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
6052             if (isZSLMode() && (NULL != pZSLChannel) && mPrepSnapRun) {
6053                 mCameraHandle->ops->stop_zsl_snapshot(
6054                         mCameraHandle->camera_handle,
6055                         pZSLChannel->getMyHandle());
6056             }
6057         }
6058         mPrepSnapRun = false;
6059         LOGI("Longshot Disabled");
6060         mLongshotEnabled = false;
6061         rc = mParameters.setLongshotEnable(mLongshotEnabled);
6062         mCACDoneReceived = FALSE;
6063         break;
6064     case CAMERA_CMD_HISTOGRAM_ON:
6065     case CAMERA_CMD_HISTOGRAM_OFF:
6066         rc = setHistogram(command == CAMERA_CMD_HISTOGRAM_ON? true : false);
6067         LOGH("Histogram -> %s",
6068               mParameters.isHistogramEnabled() ? "Enabled" : "Disabled");
6069         break;
6070 #endif
6071     case CAMERA_CMD_START_FACE_DETECTION:
6072     case CAMERA_CMD_STOP_FACE_DETECTION:
6073         mParameters.setFaceDetectionOption(command == CAMERA_CMD_START_FACE_DETECTION? true : false);
6074         rc = setFaceDetection(command == CAMERA_CMD_START_FACE_DETECTION? true : false);
6075         LOGH("FaceDetection -> %s",
6076               mParameters.isFaceDetectionEnabled() ? "Enabled" : "Disabled");
6077         break;
6078 #ifndef VANILLA_HAL
6079     case CAMERA_CMD_HISTOGRAM_SEND_DATA:
6080 #endif
6081     default:
6082         rc = NO_ERROR;
6083         break;
6084     }
6085     return rc;
6086 }
6087 
6088 /*===========================================================================
6089  * FUNCTION   : registerFaceImage
6090  *
6091  * DESCRIPTION: register face image impl
6092  *
6093  * PARAMETERS :
6094  *   @img_ptr : ptr to image buffer
6095  *   @config  : ptr to config struct about input image info
6096  *   @faceID  : [OUT] face ID to uniquely identifiy the registered face image
6097  *
6098  * RETURN     : int32_t type of status
6099  *              NO_ERROR  -- success
6100  *              none-zero failure code
6101  *==========================================================================*/
registerFaceImage(void * img_ptr,cam_pp_offline_src_config_t * config,int32_t & faceID)6102 int QCamera2HardwareInterface::registerFaceImage(void *img_ptr,
6103                                                  cam_pp_offline_src_config_t *config,
6104                                                  int32_t &faceID)
6105 {
6106     int rc = NO_ERROR;
6107     faceID = -1;
6108 
6109     if (img_ptr == NULL || config == NULL) {
6110         LOGE("img_ptr or config is NULL");
6111         return BAD_VALUE;
6112     }
6113 
6114     // allocate ion memory for source image
6115     QCameraHeapMemory *imgBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
6116     if (imgBuf == NULL) {
6117         LOGE("Unable to new heap memory obj for image buf");
6118         return NO_MEMORY;
6119     }
6120 
6121     rc = imgBuf->allocate(1, config->input_buf_planes.plane_info.frame_len, NON_SECURE);
6122     if (rc < 0) {
6123         LOGE("Unable to allocate heap memory for image buf");
6124         delete imgBuf;
6125         return NO_MEMORY;
6126     }
6127 
6128     void *pBufPtr = imgBuf->getPtr(0);
6129     if (pBufPtr == NULL) {
6130         LOGE("image buf is NULL");
6131         imgBuf->deallocate();
6132         delete imgBuf;
6133         return NO_MEMORY;
6134     }
6135     memcpy(pBufPtr, img_ptr, config->input_buf_planes.plane_info.frame_len);
6136     //Do cache ops before sending for reprocess
6137     imgBuf->cacheOps(0, ION_IOC_CLEAN_INV_CACHES);
6138 
6139     cam_pp_feature_config_t pp_feature;
6140     memset(&pp_feature, 0, sizeof(cam_pp_feature_config_t));
6141     pp_feature.feature_mask = CAM_QCOM_FEATURE_REGISTER_FACE;
6142     QCameraReprocessChannel *pChannel =
6143         addOfflineReprocChannel(*config, pp_feature, NULL, NULL);
6144 
6145     if (pChannel == NULL) {
6146         LOGE("fail to add offline reprocess channel");
6147         imgBuf->deallocate();
6148         delete imgBuf;
6149         return UNKNOWN_ERROR;
6150     }
6151 
6152     rc = pChannel->start();
6153     if (rc != NO_ERROR) {
6154         LOGE("Cannot start reprocess channel");
6155         imgBuf->deallocate();
6156         delete imgBuf;
6157         delete pChannel;
6158         return rc;
6159     }
6160 
6161     ssize_t bufSize = imgBuf->getSize(0);
6162     if (BAD_INDEX != bufSize) {
6163         rc = pChannel->doReprocess(imgBuf->getFd(0), imgBuf->getPtr(0),
6164                 (size_t)bufSize, faceID);
6165     } else {
6166         LOGE("Failed to retrieve buffer size (bad index)");
6167         return UNKNOWN_ERROR;
6168     }
6169 
6170     // done with register face image, free imgbuf and delete reprocess channel
6171     imgBuf->deallocate();
6172     delete imgBuf;
6173     imgBuf = NULL;
6174     pChannel->stop();
6175     delete pChannel;
6176     pChannel = NULL;
6177 
6178     return rc;
6179 }
6180 
6181 /*===========================================================================
6182  * FUNCTION   : release
6183  *
6184  * DESCRIPTION: release camera resource impl
6185  *
6186  * PARAMETERS : none
6187  *
6188  * RETURN     : int32_t type of status
6189  *              NO_ERROR  -- success
6190  *              none-zero failure code
6191  *==========================================================================*/
release()6192 int QCamera2HardwareInterface::release()
6193 {
6194     // stop and delete all channels
6195     for (int i = 0; i <QCAMERA_CH_TYPE_MAX ; i++) {
6196         if (m_channels[i] != NULL) {
6197             stopChannel((qcamera_ch_type_enum_t)i);
6198             delChannel((qcamera_ch_type_enum_t)i);
6199         }
6200     }
6201 
6202     return NO_ERROR;
6203 }
6204 
6205 /*===========================================================================
6206  * FUNCTION   : dump
6207  *
6208  * DESCRIPTION: camera status dump impl
6209  *
6210  * PARAMETERS :
6211  *   @fd      : fd for the buffer to be dumped with camera status
6212  *
6213  * RETURN     : int32_t type of status
6214  *              NO_ERROR  -- success
6215  *              none-zero failure code
6216  *==========================================================================*/
dump(int fd)6217 int QCamera2HardwareInterface::dump(int fd)
6218 {
6219     dprintf(fd, "\n Camera HAL information Begin \n");
6220     dprintf(fd, "Camera ID: %d \n", mCameraId);
6221     dprintf(fd, "StoreMetaDataInFrame: %d \n", mStoreMetaDataInFrame);
6222     dprintf(fd, "\n Configuration: %s", mParameters.dump().string());
6223     dprintf(fd, "\n State Information: %s", m_stateMachine.dump().string());
6224     dprintf(fd, "\n Camera HAL information End \n");
6225 
6226     /* send UPDATE_DEBUG_LEVEL to the backend so that they can read the
6227        debug level property */
6228     mParameters.updateDebugLevel();
6229     return NO_ERROR;
6230 }
6231 
6232 /*===========================================================================
6233  * FUNCTION   : processAPI
6234  *
6235  * DESCRIPTION: process API calls from upper layer
6236  *
6237  * PARAMETERS :
6238  *   @api         : API to be processed
6239  *   @api_payload : ptr to API payload if any
6240  *
6241  * RETURN     : int32_t type of status
6242  *              NO_ERROR  -- success
6243  *              none-zero failure code
6244  *==========================================================================*/
processAPI(qcamera_sm_evt_enum_t api,void * api_payload)6245 int QCamera2HardwareInterface::processAPI(qcamera_sm_evt_enum_t api, void *api_payload)
6246 {
6247     int ret = DEAD_OBJECT;
6248 
6249     if (m_smThreadActive) {
6250         ret = m_stateMachine.procAPI(api, api_payload);
6251     }
6252 
6253     return ret;
6254 }
6255 
6256 /*===========================================================================
6257  * FUNCTION   : processEvt
6258  *
6259  * DESCRIPTION: process Evt from backend via mm-camera-interface
6260  *
6261  * PARAMETERS :
6262  *   @evt         : event type to be processed
6263  *   @evt_payload : ptr to event payload if any
6264  *
6265  * RETURN     : int32_t type of status
6266  *              NO_ERROR  -- success
6267  *              none-zero failure code
6268  *==========================================================================*/
processEvt(qcamera_sm_evt_enum_t evt,void * evt_payload)6269 int QCamera2HardwareInterface::processEvt(qcamera_sm_evt_enum_t evt, void *evt_payload)
6270 {
6271     return m_stateMachine.procEvt(evt, evt_payload);
6272 }
6273 
6274 /*===========================================================================
6275  * FUNCTION   : processSyncEvt
6276  *
6277  * DESCRIPTION: process synchronous Evt from backend
6278  *
6279  * PARAMETERS :
6280  *   @evt         : event type to be processed
6281  *   @evt_payload : ptr to event payload if any
6282  *
6283  * RETURN     : int32_t type of status
6284  *              NO_ERROR  -- success
6285  *              none-zero failure code
6286  *==========================================================================*/
processSyncEvt(qcamera_sm_evt_enum_t evt,void * evt_payload)6287 int QCamera2HardwareInterface::processSyncEvt(qcamera_sm_evt_enum_t evt, void *evt_payload)
6288 {
6289     int rc = NO_ERROR;
6290 
6291     pthread_mutex_lock(&m_evtLock);
6292     rc =  processEvt(evt, evt_payload);
6293     if (rc == NO_ERROR) {
6294         memset(&m_evtResult, 0, sizeof(qcamera_api_result_t));
6295         while (m_evtResult.request_api != evt) {
6296             pthread_cond_wait(&m_evtCond, &m_evtLock);
6297         }
6298         rc =  m_evtResult.status;
6299     }
6300     pthread_mutex_unlock(&m_evtLock);
6301 
6302     return rc;
6303 }
6304 
6305 /*===========================================================================
6306  * FUNCTION   : evtHandle
6307  *
6308  * DESCRIPTION: Function registerd to mm-camera-interface to handle backend events
6309  *
6310  * PARAMETERS :
6311  *   @camera_handle : event type to be processed
6312  *   @evt           : ptr to event
6313  *   @user_data     : user data ptr
6314  *
6315  * RETURN     : none
6316  *==========================================================================*/
camEvtHandle(uint32_t,mm_camera_event_t * evt,void * user_data)6317 void QCamera2HardwareInterface::camEvtHandle(uint32_t /*camera_handle*/,
6318                                           mm_camera_event_t *evt,
6319                                           void *user_data)
6320 {
6321     QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)user_data;
6322     if (obj && evt) {
6323         mm_camera_event_t *payload =
6324             (mm_camera_event_t *)malloc(sizeof(mm_camera_event_t));
6325         if (NULL != payload) {
6326             *payload = *evt;
6327             //peek into the event, if this is an eztune event from server,
6328             //then we don't need to post it to the SM Qs, we shud directly
6329             //spawn a thread and get the job done (jpeg or raw snapshot)
6330             switch (payload->server_event_type) {
6331                 case CAM_EVENT_TYPE_INT_TAKE_JPEG:
6332                     //Received JPEG trigger from eztune
6333                     if (false == obj->m_bIntJpegEvtPending) {
6334                         pthread_mutex_lock(&obj->m_int_lock);
6335                         obj->m_bIntJpegEvtPending = true;
6336                         pthread_mutex_unlock(&obj->m_int_lock);
6337                         obj->takePictureInternal();
6338                     }
6339                     free(payload);
6340                     break;
6341                 case CAM_EVENT_TYPE_INT_TAKE_RAW:
6342                     //Received RAW trigger from eztune
6343                     if (false == obj->m_bIntRawEvtPending) {
6344                         pthread_mutex_lock(&obj->m_int_lock);
6345                         obj->m_bIntRawEvtPending = true;
6346                         pthread_mutex_unlock(&obj->m_int_lock);
6347                         obj->takePictureInternal();
6348                     }
6349                     free(payload);
6350                     break;
6351                 case CAM_EVENT_TYPE_DAEMON_DIED:
6352                     {
6353                         Mutex::Autolock l(obj->mDefLock);
6354                         obj->mDefCond.broadcast();
6355                         LOGH("broadcast mDefCond signal\n");
6356                     }
6357                 default:
6358                     obj->processEvt(QCAMERA_SM_EVT_EVT_NOTIFY, payload);
6359                     break;
6360             }
6361         }
6362     } else {
6363         LOGE("NULL user_data");
6364     }
6365 }
6366 
6367 /*===========================================================================
6368  * FUNCTION   : jpegEvtHandle
6369  *
6370  * DESCRIPTION: Function registerd to mm-jpeg-interface to handle jpeg events
6371  *
6372  * PARAMETERS :
6373  *   @status    : status of jpeg job
6374  *   @client_hdl: jpeg client handle
6375  *   @jobId     : jpeg job Id
6376  *   @p_ouput   : ptr to jpeg output result struct
6377  *   @userdata  : user data ptr
6378  *
6379  * RETURN     : none
6380  *==========================================================================*/
jpegEvtHandle(jpeg_job_status_t status,uint32_t,uint32_t jobId,mm_jpeg_output_t * p_output,void * userdata)6381 void QCamera2HardwareInterface::jpegEvtHandle(jpeg_job_status_t status,
6382                                               uint32_t /*client_hdl*/,
6383                                               uint32_t jobId,
6384                                               mm_jpeg_output_t *p_output,
6385                                               void *userdata)
6386 {
6387     QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)userdata;
6388     if (obj) {
6389         qcamera_jpeg_evt_payload_t *payload =
6390             (qcamera_jpeg_evt_payload_t *)malloc(sizeof(qcamera_jpeg_evt_payload_t));
6391         if (NULL != payload) {
6392             memset(payload, 0, sizeof(qcamera_jpeg_evt_payload_t));
6393             payload->status = status;
6394             payload->jobId = jobId;
6395             if (p_output != NULL) {
6396                 payload->out_data = *p_output;
6397             }
6398             obj->processEvt(QCAMERA_SM_EVT_JPEG_EVT_NOTIFY, payload);
6399         }
6400     } else {
6401         LOGE("NULL user_data");
6402     }
6403 }
6404 
6405 /*===========================================================================
6406  * FUNCTION   : thermalEvtHandle
6407  *
6408  * DESCRIPTION: routine to handle thermal event notification
6409  *
6410  * PARAMETERS :
6411  *   @level      : thermal level
6412  *   @userdata   : userdata passed in during registration
6413  *   @data       : opaque data from thermal client
6414  *
6415  * RETURN     : int32_t type of status
6416  *              NO_ERROR  -- success
6417  *              none-zero failure code
6418  *==========================================================================*/
thermalEvtHandle(qcamera_thermal_level_enum_t * level,void * userdata,void * data)6419 int QCamera2HardwareInterface::thermalEvtHandle(
6420         qcamera_thermal_level_enum_t *level, void *userdata, void *data)
6421 {
6422     if (!mCameraOpened) {
6423         LOGH("Camera is not opened, no need to handle thermal evt");
6424         return NO_ERROR;
6425     }
6426 
6427     // Make sure thermal events are logged
6428     LOGH("level = %d, userdata = %p, data = %p",
6429          *level, userdata, data);
6430     //We don't need to lockAPI, waitAPI here. QCAMERA_SM_EVT_THERMAL_NOTIFY
6431     // becomes an aync call. This also means we can only pass payload
6432     // by value, not by address.
6433     return processAPI(QCAMERA_SM_EVT_THERMAL_NOTIFY, (void *)level);
6434 }
6435 
6436 /*===========================================================================
6437  * FUNCTION   : sendEvtNotify
6438  *
6439  * DESCRIPTION: send event notify to notify thread
6440  *
6441  * PARAMETERS :
6442  *   @msg_type: msg type to be sent
6443  *   @ext1    : optional extension1
6444  *   @ext2    : optional extension2
6445  *
6446  * RETURN     : int32_t type of status
6447  *              NO_ERROR  -- success
6448  *              none-zero failure code
6449  *==========================================================================*/
sendEvtNotify(int32_t msg_type,int32_t ext1,int32_t ext2)6450 int32_t QCamera2HardwareInterface::sendEvtNotify(int32_t msg_type,
6451                                                  int32_t ext1,
6452                                                  int32_t ext2)
6453 {
6454     qcamera_callback_argm_t cbArg;
6455     memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
6456     cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK;
6457     cbArg.msg_type = msg_type;
6458     cbArg.ext1 = ext1;
6459     cbArg.ext2 = ext2;
6460     return m_cbNotifier.notifyCallback(cbArg);
6461 }
6462 
6463 /*===========================================================================
6464  * FUNCTION   : processAEInfo
6465  *
6466  * DESCRIPTION: process AE updates
6467  *
6468  * PARAMETERS :
6469  *   @ae_params: current AE parameters
6470  *
6471  * RETURN     : None
6472  *==========================================================================*/
processAEInfo(cam_3a_params_t & ae_params)6473 int32_t QCamera2HardwareInterface::processAEInfo(cam_3a_params_t &ae_params)
6474 {
6475     mParameters.updateAEInfo(ae_params);
6476     if (mParameters.isInstantAECEnabled()) {
6477         // Reset Instant AEC info only if instant aec enabled.
6478         bool bResetInstantAec = false;
6479         if (ae_params.settled) {
6480             // If AEC settled, reset instant AEC
6481             bResetInstantAec = true;
6482         } else if ((mParameters.isInstantCaptureEnabled()) &&
6483                 (mInstantAecFrameCount >= mParameters.getAecFrameBoundValue())) {
6484             // if AEC not settled, and instant capture enabled,
6485             // reset instant AEC only when frame count is
6486             // more or equal to AEC frame bound value.
6487             bResetInstantAec = true;
6488         } else if ((mParameters.isInstantAECEnabled()) &&
6489                 (mInstantAecFrameCount >= mParameters.getAecSkipDisplayFrameBound())) {
6490             // if AEC not settled, and only instant AEC enabled,
6491             // reset instant AEC only when frame count is
6492             // more or equal to AEC skip display frame bound value.
6493             bResetInstantAec = true;
6494         }
6495 
6496         if (bResetInstantAec) {
6497             LOGD("setting instant AEC to false");
6498             mParameters.setInstantAEC(false, true);
6499             mInstantAecFrameCount = 0;
6500         }
6501     }
6502     return NO_ERROR;
6503 }
6504 
6505 /*===========================================================================
6506  * FUNCTION   : processFocusPositionInfo
6507  *
6508  * DESCRIPTION: process AF updates
6509  *
6510  * PARAMETERS :
6511  *   @cur_pos_info: current lens position
6512  *
6513  * RETURN     : None
6514  *==========================================================================*/
processFocusPositionInfo(cam_focus_pos_info_t & cur_pos_info)6515 int32_t QCamera2HardwareInterface::processFocusPositionInfo(cam_focus_pos_info_t &cur_pos_info)
6516 {
6517     mParameters.updateCurrentFocusPosition(cur_pos_info);
6518     return NO_ERROR;
6519 }
6520 
6521 /*===========================================================================
6522  * FUNCTION   : processAutoFocusEvent
6523  *
6524  * DESCRIPTION: process auto focus event
6525  *
6526  * PARAMETERS :
6527  *   @focus_data: struct containing auto focus result info
6528  *
6529  * RETURN     : int32_t type of status
6530  *              NO_ERROR  -- success
6531  *              none-zero failure code
6532  *==========================================================================*/
processAutoFocusEvent(cam_auto_focus_data_t & focus_data)6533 int32_t QCamera2HardwareInterface::processAutoFocusEvent(cam_auto_focus_data_t &focus_data)
6534 {
6535     int32_t ret = NO_ERROR;
6536     LOGH("E");
6537 
6538     if (getRelatedCamSyncInfo()->mode == CAM_MODE_SECONDARY) {
6539         // Ignore focus updates
6540         LOGH("X Secondary Camera, no need to process!! ");
6541         return ret;
6542     }
6543     cam_focus_mode_type focusMode = mParameters.getFocusMode();
6544     LOGH("[AF_DBG]  focusMode=%d, focusState=%d isDepth=%d",
6545              focusMode, focus_data.focus_state, focus_data.isDepth);
6546 
6547     switch (focusMode) {
6548     case CAM_FOCUS_MODE_AUTO:
6549     case CAM_FOCUS_MODE_MACRO:
6550         // ignore AF event if AF was already cancelled meanwhile
6551         if (!mActiveAF) {
6552             break;
6553         }
6554         // If the HAL focus mode is different from AF INFINITY focus mode, send event to app
6555         if ((focus_data.focus_mode == CAM_FOCUS_MODE_INFINITY) &&
6556                 (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) {
6557             ret = sendEvtNotify(CAMERA_MSG_FOCUS, true, 0);
6558             mActiveAF = false; // reset the mActiveAF in this special case
6559             break;
6560         }
6561 
6562         //while transitioning from CAF->Auto/Macro, we might receive CAF related
6563         //events (PASSIVE_*) due to timing. Ignore such events if any.
6564         if ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN) ||
6565                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
6566                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED)) {
6567             break;
6568         }
6569 
6570         //This is just an intermediate update to HAL indicating focus is in progress. No need
6571         //to send this event to app. Same applies to INACTIVE state as well.
6572         if ((focus_data.focus_state == CAM_AF_STATE_ACTIVE_SCAN) ||
6573                 (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) {
6574             break;
6575         }
6576         // update focus distance
6577         mParameters.updateFocusDistances(&focus_data.focus_dist);
6578 
6579         //flush any old snapshot frames in ZSL Q which are not focused.
6580         if (mParameters.isZSLMode() && focus_data.flush_info.needFlush ) {
6581             QCameraPicChannel *pZSLChannel =
6582                     (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
6583             if (NULL != pZSLChannel) {
6584                 //flush the zsl-buffer
6585                 uint32_t flush_frame_idx = focus_data.flush_info.focused_frame_idx;
6586                 LOGD("flush the zsl-buffer before frame = %u.", flush_frame_idx);
6587                 pZSLChannel->flushSuperbuffer(flush_frame_idx);
6588             }
6589         }
6590 
6591         //send event to app finally
6592         LOGI("Send AF DOne event to app");
6593         ret = sendEvtNotify(CAMERA_MSG_FOCUS,
6594                             (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED), 0);
6595         break;
6596     case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
6597     case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
6598 
6599         // If the HAL focus mode is different from AF INFINITY focus mode, send event to app
6600         if ((focus_data.focus_mode == CAM_FOCUS_MODE_INFINITY) &&
6601                 (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) {
6602             ret = sendEvtNotify(CAMERA_MSG_FOCUS, false, 0);
6603             mActiveAF = false; // reset the mActiveAF in this special case
6604             break;
6605         }
6606 
6607         //If AutoFocus() is triggered while in CAF mode, ignore all CAF events (PASSIVE_*) and
6608         //process/wait for only ACTIVE_* events.
6609         if (((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
6610                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED) ||
6611                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN)) && mActiveAF) {
6612             break;
6613         }
6614 
6615         if (!bDepthAFCallbacks && focus_data.isDepth &&
6616                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN)) {
6617             LOGD("Skip sending scan state to app, if depth focus");
6618             break;
6619         }
6620 
6621         //These are the AF states for which we need to send notification to app in CAF mode.
6622         //This includes both regular CAF (PASSIVE) events as well as ACTIVE events ( in case
6623         //AF is triggered while in CAF mode)
6624         if ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
6625                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED) ||
6626                 (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED) ||
6627                 (focus_data.focus_state == CAM_AF_STATE_NOT_FOCUSED_LOCKED)) {
6628 
6629             // update focus distance
6630             mParameters.updateFocusDistances(&focus_data.focus_dist);
6631 
6632             if (mParameters.isZSLMode() && focus_data.flush_info.needFlush ) {
6633                 QCameraPicChannel *pZSLChannel =
6634                         (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
6635                 if (NULL != pZSLChannel) {
6636                     //flush the zsl-buffer
6637                     uint32_t flush_frame_idx = focus_data.flush_info.focused_frame_idx;
6638                     LOGD("flush the zsl-buffer before frame = %u.", flush_frame_idx);
6639                     pZSLChannel->flushSuperbuffer(flush_frame_idx);
6640                 }
6641             }
6642 
6643             if (mActiveAF) {
6644                 LOGI("Send AF Done event to app");
6645             }
6646             ret = sendEvtNotify(CAMERA_MSG_FOCUS,
6647                     ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
6648                     (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED)), 0);
6649         }
6650         ret = sendEvtNotify(CAMERA_MSG_FOCUS_MOVE,
6651                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN), 0);
6652         break;
6653     case CAM_FOCUS_MODE_INFINITY:
6654     case CAM_FOCUS_MODE_FIXED:
6655     case CAM_FOCUS_MODE_EDOF:
6656     default:
6657         LOGH("no ops for autofocus event in focusmode %d", focusMode);
6658         break;
6659     }
6660 
6661     //Reset mActiveAF once we receive focus done event
6662     if ((focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED) ||
6663             (focus_data.focus_state == CAM_AF_STATE_NOT_FOCUSED_LOCKED)) {
6664         mActiveAF = false;
6665     }
6666 
6667     LOGH("X");
6668     return ret;
6669 }
6670 
6671 /*===========================================================================
6672  * FUNCTION   : processZoomEvent
6673  *
6674  * DESCRIPTION: process zoom event
6675  *
6676  * PARAMETERS :
6677  *   @crop_info : crop info as a result of zoom operation
6678  *
6679  * RETURN     : int32_t type of status
6680  *              NO_ERROR  -- success
6681  *              none-zero failure code
6682  *==========================================================================*/
processZoomEvent(cam_crop_data_t & crop_info)6683 int32_t QCamera2HardwareInterface::processZoomEvent(cam_crop_data_t &crop_info)
6684 {
6685     int32_t ret = NO_ERROR;
6686 
6687     for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
6688         if (m_channels[i] != NULL) {
6689             ret = m_channels[i]->processZoomDone(mPreviewWindow, crop_info);
6690         }
6691     }
6692     return ret;
6693 }
6694 
6695 /*===========================================================================
6696  * FUNCTION   : processZSLCaptureDone
6697  *
6698  * DESCRIPTION: process ZSL capture done events
6699  *
6700  * PARAMETERS : None
6701  *
6702  * RETURN     : int32_t type of status
6703  *              NO_ERROR  -- success
6704  *              none-zero failure code
6705  *==========================================================================*/
processZSLCaptureDone()6706 int32_t QCamera2HardwareInterface::processZSLCaptureDone()
6707 {
6708     int rc = NO_ERROR;
6709 
6710     if (++mInputCount >= mParameters.getBurstCountForAdvancedCapture()) {
6711         rc = unconfigureAdvancedCapture();
6712     }
6713 
6714     return rc;
6715 }
6716 
6717 /*===========================================================================
6718  * FUNCTION   : processRetroAECUnlock
6719  *
6720  * DESCRIPTION: process retro burst AEC unlock events
6721  *
6722  * PARAMETERS : None
6723  *
6724  * RETURN     : int32_t type of status
6725  *              NO_ERROR  -- success
6726  *              none-zero failure code
6727  *==========================================================================*/
processRetroAECUnlock()6728 int32_t QCamera2HardwareInterface::processRetroAECUnlock()
6729 {
6730     int rc = NO_ERROR;
6731 
6732     LOGH("LED assisted AF Release AEC Lock");
6733     rc = mParameters.setAecLock("false");
6734     if (NO_ERROR != rc) {
6735         LOGE("Error setting AEC lock");
6736         return rc;
6737     }
6738 
6739     rc = mParameters.commitParameters();
6740     if (NO_ERROR != rc) {
6741         LOGE("Error during camera parameter commit");
6742     } else {
6743         m_bLedAfAecLock = FALSE;
6744     }
6745 
6746     return rc;
6747 }
6748 
6749 /*===========================================================================
6750  * FUNCTION   : processHDRData
6751  *
6752  * DESCRIPTION: process HDR scene events
6753  *
6754  * PARAMETERS :
6755  *   @hdr_scene : HDR scene event data
6756  *
6757  * RETURN     : int32_t type of status
6758  *              NO_ERROR  -- success
6759  *              none-zero failure code
6760  *==========================================================================*/
processHDRData(__unused cam_asd_hdr_scene_data_t hdr_scene)6761 int32_t QCamera2HardwareInterface::processHDRData(
6762         __unused cam_asd_hdr_scene_data_t hdr_scene)
6763 {
6764     int rc = NO_ERROR;
6765 
6766 #ifndef VANILLA_HAL
6767     if (hdr_scene.is_hdr_scene &&
6768       (hdr_scene.hdr_confidence > HDR_CONFIDENCE_THRESHOLD) &&
6769       mParameters.isAutoHDREnabled()) {
6770         m_HDRSceneEnabled = true;
6771     } else {
6772         m_HDRSceneEnabled = false;
6773     }
6774     mParameters.setHDRSceneEnable(m_HDRSceneEnabled);
6775 
6776     if ( msgTypeEnabled(CAMERA_MSG_META_DATA) ) {
6777 
6778         size_t data_len = sizeof(int);
6779         size_t buffer_len = 1 *sizeof(int)       //meta type
6780                           + 1 *sizeof(int)       //data len
6781                           + 1 *sizeof(int);      //data
6782         camera_memory_t *hdrBuffer = mGetMemory(-1,
6783                                                  buffer_len,
6784                                                  1,
6785                                                  mCallbackCookie);
6786         if ( NULL == hdrBuffer ) {
6787             LOGE("Not enough memory for auto HDR data");
6788             return NO_MEMORY;
6789         }
6790 
6791         int *pHDRData = (int *)hdrBuffer->data;
6792         if (pHDRData == NULL) {
6793             LOGE("memory data ptr is NULL");
6794             return UNKNOWN_ERROR;
6795         }
6796 
6797         pHDRData[0] = CAMERA_META_DATA_HDR;
6798         pHDRData[1] = (int)data_len;
6799         pHDRData[2] = m_HDRSceneEnabled;
6800 
6801         qcamera_callback_argm_t cbArg;
6802         memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
6803         cbArg.cb_type = QCAMERA_DATA_CALLBACK;
6804         cbArg.msg_type = CAMERA_MSG_META_DATA;
6805         cbArg.data = hdrBuffer;
6806         cbArg.user_data = hdrBuffer;
6807         cbArg.cookie = this;
6808         cbArg.release_cb = releaseCameraMemory;
6809         rc = m_cbNotifier.notifyCallback(cbArg);
6810         if (rc != NO_ERROR) {
6811             LOGE("fail sending auto HDR notification");
6812             hdrBuffer->release(hdrBuffer);
6813         }
6814     }
6815 
6816     LOGH("hdr_scene_data: processHDRData: %d %f",
6817           hdr_scene.is_hdr_scene,
6818           hdr_scene.hdr_confidence);
6819 
6820 #endif
6821   return rc;
6822 }
6823 
6824 /*===========================================================================
6825  * FUNCTION   : transAwbMetaToParams
6826  *
6827  * DESCRIPTION: translate awb params from metadata callback to QCameraParametersIntf
6828  *
6829  * PARAMETERS :
6830  *   @awb_params : awb params from metadata callback
6831  *
6832  * RETURN     : int32_t type of status
6833  *              NO_ERROR  -- success
6834  *              none-zero failure code
6835  *==========================================================================*/
transAwbMetaToParams(cam_awb_params_t & awb_params)6836 int32_t QCamera2HardwareInterface::transAwbMetaToParams(cam_awb_params_t &awb_params)
6837 {
6838     mParameters.updateAWBParams(awb_params);
6839     return NO_ERROR;
6840 }
6841 
6842 /*===========================================================================
6843  * FUNCTION   : processPrepSnapshotDone
6844  *
6845  * DESCRIPTION: process prep snapshot done event
6846  *
6847  * PARAMETERS :
6848  *   @prep_snapshot_state  : state of prepare snapshot done. In other words,
6849  *                           i.e. whether need future frames for capture.
6850  *
6851  * RETURN     : int32_t type of status
6852  *              NO_ERROR  -- success
6853  *              none-zero failure code
6854  *==========================================================================*/
processPrepSnapshotDoneEvent(cam_prep_snapshot_state_t prep_snapshot_state)6855 int32_t QCamera2HardwareInterface::processPrepSnapshotDoneEvent(
6856                         cam_prep_snapshot_state_t prep_snapshot_state)
6857 {
6858     int32_t ret = NO_ERROR;
6859     LOGI("[KPI Perf]: Received PREPARE SANSPHOT Done event state = %d",
6860             prep_snapshot_state);
6861     if (m_channels[QCAMERA_CH_TYPE_ZSL] &&
6862         prep_snapshot_state == NEED_FUTURE_FRAME) {
6863         LOGH("already handled in mm-camera-intf, no ops here");
6864         if (isRetroPicture()) {
6865             mParameters.setAecLock("true");
6866             mParameters.commitParameters();
6867             m_bLedAfAecLock = TRUE;
6868         }
6869     }
6870     return ret;
6871 }
6872 
6873 /*===========================================================================
6874  * FUNCTION   : processASDUpdate
6875  *
6876  * DESCRIPTION: process ASD update event
6877  *
6878  * PARAMETERS :
6879  *   @scene: selected scene mode
6880  *
6881  * RETURN     : int32_t type of status
6882  *              NO_ERROR  -- success
6883  *              none-zero failure code
6884  *==========================================================================*/
processASDUpdate(__unused cam_asd_decision_t asd_decision)6885 int32_t QCamera2HardwareInterface::processASDUpdate(
6886         __unused cam_asd_decision_t asd_decision)
6887 {
6888 #ifndef VANILLA_HAL
6889     if ( msgTypeEnabled(CAMERA_MSG_META_DATA) ) {
6890         size_t data_len = sizeof(cam_auto_scene_t);
6891         size_t buffer_len = 1 *sizeof(int)       //meta type
6892                 + 1 *sizeof(int)       //data len
6893                 + data_len;            //data
6894         camera_memory_t *asdBuffer = mGetMemory(-1,
6895                 buffer_len, 1, mCallbackCookie);
6896         if ( NULL == asdBuffer ) {
6897             LOGE("Not enough memory for histogram data");
6898             return NO_MEMORY;
6899         }
6900 
6901         int *pASDData = (int *)asdBuffer->data;
6902         if (pASDData == NULL) {
6903             LOGE("memory data ptr is NULL");
6904             return UNKNOWN_ERROR;
6905         }
6906 
6907         pASDData[0] = CAMERA_META_DATA_ASD;
6908         pASDData[1] = (int)data_len;
6909         pASDData[2] = asd_decision.detected_scene;
6910 
6911         qcamera_callback_argm_t cbArg;
6912         memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
6913         cbArg.cb_type = QCAMERA_DATA_CALLBACK;
6914         cbArg.msg_type = CAMERA_MSG_META_DATA;
6915         cbArg.data = asdBuffer;
6916         cbArg.user_data = asdBuffer;
6917         cbArg.cookie = this;
6918         cbArg.release_cb = releaseCameraMemory;
6919         int32_t rc = m_cbNotifier.notifyCallback(cbArg);
6920         if (rc != NO_ERROR) {
6921             LOGE("fail sending notification");
6922             asdBuffer->release(asdBuffer);
6923         }
6924     }
6925 #endif
6926     return NO_ERROR;
6927 }
6928 
6929 /*===========================================================================
6930  * FUNCTION   : processJpegNotify
6931  *
6932  * DESCRIPTION: process jpeg event
6933  *
6934  * PARAMETERS :
6935  *   @jpeg_evt: ptr to jpeg event payload
6936  *
6937  * RETURN     : int32_t type of status
6938  *              NO_ERROR  -- success
6939  *              none-zero failure code
6940  *==========================================================================*/
processJpegNotify(qcamera_jpeg_evt_payload_t * jpeg_evt)6941 int32_t QCamera2HardwareInterface::processJpegNotify(qcamera_jpeg_evt_payload_t *jpeg_evt)
6942 {
6943     return m_postprocessor.processJpegEvt(jpeg_evt);
6944 }
6945 
6946 
6947 /*===========================================================================
6948  * FUNCTION   : processDualCamFovControl
6949  *
6950  * DESCRIPTION: Based on the result collected from FOV control-
6951  *              1. Switch the master camera if needed
6952  *              2. Toggle the Low Power Mode for slave camera
6953  *
6954  * PARAMETERS : none
6955  *
6956  * RETURN     : none
6957  *==========================================================================*/
processDualCamFovControl()6958 void QCamera2HardwareInterface::processDualCamFovControl()
6959 {
6960    uint32_t camState;
6961    fov_control_result_t fovControlResult;
6962 
6963     if (!isDualCamera()) {
6964         return;
6965     }
6966 
6967     fovControlResult = m_pFovControl->getFovControlResult();
6968 
6969     camState = fovControlResult.activeCamState;
6970 
6971     if (camState != mActiveCamera) {
6972         processCameraControl(camState);
6973     }
6974 
6975     if (mMasterCamera != fovControlResult.camMasterPreview) {
6976         mMasterCamera = fovControlResult.camMasterPreview;
6977         switchCameraCb();
6978     }
6979 }
6980 
6981 /*===========================================================================
6982  * FUNCTION   : processCameraControl
6983  *
6984  * DESCRIPTION: Suspend and resume camera
6985  *
6986  * PARAMETERS :
6987  *
6988  * RETURN     : int32_t type of status
6989  *              NO_ERROR  -- success
6990  *              none-zero failure code
6991  *==========================================================================*/
processCameraControl(uint32_t camState)6992 int32_t QCamera2HardwareInterface::processCameraControl(uint32_t camState)
6993 {
6994     int32_t ret = NO_ERROR;
6995 
6996     //Set camera controls to parameter and back-end
6997     ret = mParameters.setCameraControls(camState);
6998 
6999     //Update camera status to internal channel
7000     for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
7001         if (m_channels[i] != NULL && m_channels[i]->isDualChannel()) {
7002             ret = m_channels[i]->processCameraControl(camState);
7003             if (ret != NO_ERROR) {
7004                 LOGE("Channel Switch Failed");
7005                 break;
7006             }
7007         }
7008     }
7009     if (ret == NO_ERROR) {
7010         if (camState == MM_CAMERA_TYPE_MAIN) {
7011             m_ActiveHandle = get_main_camera_handle(mCameraHandle->camera_handle);
7012         } else if (camState == MM_CAMERA_TYPE_AUX) {
7013             m_ActiveHandle = get_aux_camera_handle(mCameraHandle->camera_handle);
7014         }
7015     }
7016     LOGH("mActiveCamera = %d to %d", mActiveCamera, camState);
7017     mActiveCamera = camState;
7018     return ret;
7019 }
7020 
7021 /*===========================================================================
7022  * FUNCTION   : switchCameraCb
7023  *
7024  * DESCRIPTION: switch camera's in case of dual camera
7025  *
7026  * PARAMETERS :
7027  *
7028  * RETURN     : int32_t type of status
7029  *              NO_ERROR  -- success
7030  *              none-zero failure code
7031  *==========================================================================*/
switchCameraCb()7032 int32_t QCamera2HardwareInterface::switchCameraCb()
7033 {
7034     int32_t ret = NO_ERROR;
7035 
7036     for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
7037         if (m_channels[i] != NULL && m_channels[i]->isDualChannel()) {
7038             ret = m_channels[i]->switchChannelCb();
7039             if (ret != NO_ERROR) {
7040                 LOGE("Channel Switch Failed");
7041                 break;
7042             }
7043         }
7044     }
7045 
7046     if (ret == NO_ERROR && mActiveCamera == MM_CAMERA_DUAL_CAM) {
7047         //Trigger Event to modules to update Master info
7048         mParameters.setSwitchCamera();
7049 
7050         //Change active handle
7051         if (get_aux_camera_handle(mCameraHandle->camera_handle)
7052                 == m_ActiveHandle) {
7053             m_ActiveHandle = get_main_camera_handle(mCameraHandle->camera_handle);
7054         } else if (get_main_camera_handle(mCameraHandle->camera_handle)
7055                 == m_ActiveHandle) {
7056             m_ActiveHandle = get_aux_camera_handle(mCameraHandle->camera_handle);
7057         } else {
7058             m_ActiveHandle = mCameraHandle->camera_handle;
7059         }
7060     }
7061     return ret;
7062 }
7063 
7064 /*===========================================================================
7065  * FUNCTION   : lockAPI
7066  *
7067  * DESCRIPTION: lock to process API
7068  *
7069  * PARAMETERS : none
7070  *
7071  * RETURN     : none
7072  *==========================================================================*/
lockAPI()7073 void QCamera2HardwareInterface::lockAPI()
7074 {
7075     pthread_mutex_lock(&m_lock);
7076 }
7077 
7078 /*===========================================================================
7079  * FUNCTION   : waitAPIResult
7080  *
7081  * DESCRIPTION: wait for API result coming back. This is a blocking call, it will
7082  *              return only cerntain API event type arrives
7083  *
7084  * PARAMETERS :
7085  *   @api_evt : API event type
7086  *
7087  * RETURN     : none
7088  *==========================================================================*/
waitAPIResult(qcamera_sm_evt_enum_t api_evt,qcamera_api_result_t * apiResult)7089 void QCamera2HardwareInterface::waitAPIResult(qcamera_sm_evt_enum_t api_evt,
7090         qcamera_api_result_t *apiResult)
7091 {
7092     LOGD("wait for API result of evt (%d)", api_evt);
7093     int resultReceived = 0;
7094     while  (!resultReceived) {
7095         pthread_cond_wait(&m_cond, &m_lock);
7096         if (m_apiResultList != NULL) {
7097             api_result_list *apiResultList = m_apiResultList;
7098             api_result_list *apiResultListPrevious = m_apiResultList;
7099             while (apiResultList != NULL) {
7100                 if (apiResultList->result.request_api == api_evt) {
7101                     resultReceived = 1;
7102                     *apiResult = apiResultList->result;
7103                     apiResultListPrevious->next = apiResultList->next;
7104                     if (apiResultList == m_apiResultList) {
7105                         m_apiResultList = apiResultList->next;
7106                     }
7107                     free(apiResultList);
7108                     break;
7109                 }
7110                 else {
7111                     apiResultListPrevious = apiResultList;
7112                     apiResultList = apiResultList->next;
7113                 }
7114             }
7115         }
7116     }
7117     LOGD("return (%d) from API result wait for evt (%d)",
7118            apiResult->status, api_evt);
7119 }
7120 
7121 
7122 /*===========================================================================
7123  * FUNCTION   : unlockAPI
7124  *
7125  * DESCRIPTION: API processing is done, unlock
7126  *
7127  * PARAMETERS : none
7128  *
7129  * RETURN     : none
7130  *==========================================================================*/
unlockAPI()7131 void QCamera2HardwareInterface::unlockAPI()
7132 {
7133     pthread_mutex_unlock(&m_lock);
7134 }
7135 
7136 /*===========================================================================
7137  * FUNCTION   : signalAPIResult
7138  *
7139  * DESCRIPTION: signal condition viarable that cerntain API event type arrives
7140  *
7141  * PARAMETERS :
7142  *   @result  : API result
7143  *
7144  * RETURN     : none
7145  *==========================================================================*/
signalAPIResult(qcamera_api_result_t * result)7146 void QCamera2HardwareInterface::signalAPIResult(qcamera_api_result_t *result)
7147 {
7148 
7149     pthread_mutex_lock(&m_lock);
7150     api_result_list *apiResult = (api_result_list *)malloc(sizeof(api_result_list));
7151     if (apiResult == NULL) {
7152         LOGE("ERROR: malloc for api result failed, Result will not be sent");
7153         goto malloc_failed;
7154     }
7155     apiResult->result = *result;
7156     apiResult->next = NULL;
7157     if (m_apiResultList == NULL) m_apiResultList = apiResult;
7158     else {
7159         api_result_list *apiResultList = m_apiResultList;
7160         while(apiResultList->next != NULL) apiResultList = apiResultList->next;
7161         apiResultList->next = apiResult;
7162     }
7163 malloc_failed:
7164     pthread_cond_broadcast(&m_cond);
7165     pthread_mutex_unlock(&m_lock);
7166 }
7167 
7168 /*===========================================================================
7169  * FUNCTION   : signalEvtResult
7170  *
7171  * DESCRIPTION: signal condition variable that certain event was processed
7172  *
7173  * PARAMETERS :
7174  *   @result  : Event result
7175  *
7176  * RETURN     : none
7177  *==========================================================================*/
signalEvtResult(qcamera_api_result_t * result)7178 void QCamera2HardwareInterface::signalEvtResult(qcamera_api_result_t *result)
7179 {
7180     pthread_mutex_lock(&m_evtLock);
7181     m_evtResult = *result;
7182     pthread_cond_signal(&m_evtCond);
7183     pthread_mutex_unlock(&m_evtLock);
7184 }
7185 
prepareRawStream(QCameraChannel * curChannel)7186 int32_t QCamera2HardwareInterface::prepareRawStream(QCameraChannel *curChannel)
7187 {
7188     int32_t rc = NO_ERROR;
7189     cam_dimension_t str_dim,max_dim;
7190     QCameraChannel *pChannel;
7191 
7192     max_dim.width = 0;
7193     max_dim.height = 0;
7194 
7195     for (int j = 0; j < QCAMERA_CH_TYPE_MAX; j++) {
7196         if (m_channels[j] != NULL) {
7197             pChannel = m_channels[j];
7198             for (uint8_t i = 0; i < pChannel->getNumOfStreams(); i++) {
7199                 QCameraStream *pStream = pChannel->getStreamByIndex(i);
7200                 if (pStream != NULL) {
7201                     if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA))
7202                             || (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW))) {
7203                         continue;
7204                     }
7205                     pStream->getFrameDimension(str_dim);
7206                     if (str_dim.width > max_dim.width) {
7207                         max_dim.width = str_dim.width;
7208                     }
7209                     if (str_dim.height > max_dim.height) {
7210                         max_dim.height = str_dim.height;
7211                     }
7212                 }
7213             }
7214         }
7215     }
7216 
7217     for (uint8_t i = 0; i < curChannel->getNumOfStreams(); i++) {
7218         QCameraStream *pStream = curChannel->getStreamByIndex(i);
7219         if (pStream != NULL) {
7220             if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA))
7221                     || (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW))) {
7222                 continue;
7223             }
7224             pStream->getFrameDimension(str_dim);
7225             if (str_dim.width > max_dim.width) {
7226                 max_dim.width = str_dim.width;
7227             }
7228             if (str_dim.height > max_dim.height) {
7229                 max_dim.height = str_dim.height;
7230             }
7231         }
7232     }
7233     rc = mParameters.updateRAW(max_dim);
7234     return rc;
7235 }
7236 
7237 /*===========================================================================
7238  * FUNCTION   : addStreamToChannel
7239  *
7240  * DESCRIPTION: add a stream into a channel
7241  *
7242  * PARAMETERS :
7243  *   @pChannel   : ptr to channel obj
7244  *   @streamType : type of stream to be added
7245  *   @streamCB   : callback of stream
7246  *   @userData   : user data ptr to callback
7247  *
7248  * RETURN     : int32_t type of status
7249  *              NO_ERROR  -- success
7250  *              none-zero failure code
7251  *==========================================================================*/
addStreamToChannel(QCameraChannel * pChannel,cam_stream_type_t streamType,stream_cb_routine streamCB,void * userData)7252 int32_t QCamera2HardwareInterface::addStreamToChannel(QCameraChannel *pChannel,
7253                                                       cam_stream_type_t streamType,
7254                                                       stream_cb_routine streamCB,
7255                                                       void *userData)
7256 {
7257     int32_t rc = NO_ERROR;
7258     QCameraHeapMemory *pStreamInfo = NULL;
7259 
7260     if (streamType == CAM_STREAM_TYPE_RAW) {
7261         prepareRawStream(pChannel);
7262     }
7263 
7264     pStreamInfo = allocateStreamInfoBuf(streamType, getStreamRefCount(streamType));
7265     if (pStreamInfo == NULL) {
7266         LOGE("no mem for stream info buf");
7267         return NO_MEMORY;
7268     }
7269 
7270     bool bDynAllocBuf = false;
7271     if (isZSLMode() && streamType == CAM_STREAM_TYPE_SNAPSHOT) {
7272         bDynAllocBuf = true;
7273     }
7274 
7275     cam_padding_info_t padding_info;
7276 
7277     if (streamType == CAM_STREAM_TYPE_ANALYSIS) {
7278         cam_analysis_info_t analysisInfo;
7279         cam_feature_mask_t featureMask;
7280 
7281         featureMask = 0;
7282         mParameters.getStreamPpMask(CAM_STREAM_TYPE_ANALYSIS, featureMask);
7283         rc = mParameters.getAnalysisInfo(
7284                 ((mParameters.getRecordingHintValue() == true) &&
7285                  mParameters.fdModeInVideo()),
7286                 FALSE,
7287                 featureMask,
7288                 &analysisInfo);
7289         if (rc != NO_ERROR) {
7290             LOGE("getAnalysisInfo failed, ret = %d", rc);
7291             return rc;
7292         }
7293 
7294         padding_info = analysisInfo.analysis_padding_info;
7295     } else {
7296         padding_info =
7297                 gCamCapability[mCameraId]->padding_info;
7298         if (streamType == CAM_STREAM_TYPE_PREVIEW || streamType == CAM_STREAM_TYPE_POSTVIEW) {
7299             padding_info.width_padding = mSurfaceStridePadding;
7300             padding_info.height_padding = CAM_PAD_TO_2;
7301         }
7302         if((!needReprocess())
7303                 || (streamType != CAM_STREAM_TYPE_SNAPSHOT)
7304                 || (!mParameters.isLLNoiseEnabled())) {
7305             padding_info.offset_info.offset_x = 0;
7306             padding_info.offset_info.offset_y = 0;
7307         }
7308     }
7309 
7310     bool deferAllocation = needDeferred(streamType);
7311     LOGD("deferAllocation = %d bDynAllocBuf = %d, stream type = %d",
7312             deferAllocation, bDynAllocBuf, streamType);
7313     rc = pChannel->addStream(*this,
7314             pStreamInfo,
7315             NULL,
7316             &padding_info,
7317             streamCB, userData,
7318             bDynAllocBuf,
7319             deferAllocation);
7320 
7321     if (rc != NO_ERROR) {
7322         LOGE("add stream type (%d) failed, ret = %d",
7323                streamType, rc);
7324         return rc;
7325     }
7326 
7327     return rc;
7328 }
7329 
7330 /*===========================================================================
7331  * FUNCTION   : addPreviewChannel
7332  *
7333  * DESCRIPTION: add a preview channel that contains a preview stream
7334  *
7335  * PARAMETERS : none
7336  *
7337  * RETURN     : int32_t type of status
7338  *              NO_ERROR  -- success
7339  *              none-zero failure code
7340  *==========================================================================*/
addPreviewChannel()7341 int32_t QCamera2HardwareInterface::addPreviewChannel()
7342 {
7343     int32_t rc = NO_ERROR;
7344     QCameraChannel *pChannel = NULL;
7345     char value[PROPERTY_VALUE_MAX];
7346     bool raw_yuv = false;
7347 
7348 
7349     if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
7350         // if we had preview channel before, delete it first
7351         delete m_channels[QCAMERA_CH_TYPE_PREVIEW];
7352         m_channels[QCAMERA_CH_TYPE_PREVIEW] = NULL;
7353     }
7354 
7355     uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_PREVIEW);
7356     pChannel = new QCameraChannel(handle, mCameraHandle->ops);
7357     if (NULL == pChannel) {
7358         LOGE("no mem for preview channel");
7359         return NO_MEMORY;
7360     }
7361 
7362     // preview only channel, don't need bundle attr and cb
7363     rc = pChannel->init(NULL, NULL, NULL);
7364     if (rc != NO_ERROR) {
7365         LOGE("init preview channel failed, ret = %d", rc);
7366         delete pChannel;
7367         return rc;
7368     }
7369 
7370     // meta data stream always coexists with preview if applicable
7371     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
7372             metadata_stream_cb_routine, this);
7373     if (rc != NO_ERROR) {
7374         LOGE("add metadata stream failed, ret = %d", rc);
7375         delete pChannel;
7376         return rc;
7377     }
7378 
7379     if (isRdiMode()) {
7380         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
7381                 rdi_mode_stream_cb_routine, this);
7382     } else {
7383         if (isNoDisplayMode()) {
7384             rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
7385                     nodisplay_preview_stream_cb_routine, this);
7386         } else {
7387             rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
7388                     preview_stream_cb_routine, this);
7389             if (needSyncCB(CAM_STREAM_TYPE_PREVIEW) == TRUE) {
7390                 pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
7391                         synchronous_stream_cb_routine);
7392             }
7393         }
7394     }
7395 
7396     if (rc != NO_ERROR) {
7397         LOGE("add raw/preview stream failed, ret = %d", rc);
7398         delete pChannel;
7399         return rc;
7400     }
7401 
7402     if (((mParameters.fdModeInVideo())
7403             || (mParameters.getDcrf() == true)
7404             || (mParameters.getRecordingHintValue() != true))
7405             && (!mParameters.isSecureMode())) {
7406         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
7407                 NULL, this);
7408         if (rc != NO_ERROR) {
7409             LOGE("add Analysis stream failed, ret = %d", rc);
7410             delete pChannel;
7411             return rc;
7412         }
7413     }
7414 
7415     property_get("persist.camera.raw_yuv", value, "0");
7416     raw_yuv = atoi(value) > 0 ? true : false;
7417     if ( raw_yuv ) {
7418         rc = addStreamToChannel(pChannel,CAM_STREAM_TYPE_RAW,
7419                 preview_raw_stream_cb_routine,this);
7420         if ( rc != NO_ERROR ) {
7421             LOGE("add raw stream failed, ret = %d", __FUNCTION__, rc);
7422             delete pChannel;
7423             return rc;
7424         }
7425     }
7426 
7427     if (rc != NO_ERROR) {
7428         LOGE("add preview stream failed, ret = %d", rc);
7429         delete pChannel;
7430         return rc;
7431     }
7432 
7433     m_channels[QCAMERA_CH_TYPE_PREVIEW] = pChannel;
7434     return rc;
7435 }
7436 
7437 /*===========================================================================
7438  * FUNCTION   : addVideoChannel
7439  *
7440  * DESCRIPTION: add a video channel that contains a video stream
7441  *
7442  * PARAMETERS : none
7443  *
7444  * RETURN     : int32_t type of status
7445  *              NO_ERROR  -- success
7446  *              none-zero failure code
7447  *==========================================================================*/
addVideoChannel()7448 int32_t QCamera2HardwareInterface::addVideoChannel()
7449 {
7450     int32_t rc = NO_ERROR;
7451     QCameraVideoChannel *pChannel = NULL;
7452 
7453     if (m_channels[QCAMERA_CH_TYPE_VIDEO] != NULL) {
7454         // if we had video channel before, delete it first
7455         delete m_channels[QCAMERA_CH_TYPE_VIDEO];
7456         m_channels[QCAMERA_CH_TYPE_VIDEO] = NULL;
7457     }
7458 
7459     uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_VIDEO);
7460     pChannel = new QCameraVideoChannel(handle, mCameraHandle->ops);
7461     if (NULL == pChannel) {
7462         LOGE("no mem for video channel");
7463         return NO_MEMORY;
7464     }
7465 
7466     if (isLowPowerMode()) {
7467         mm_camera_channel_attr_t attr;
7468         memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
7469         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
7470         attr.look_back = 0; //wait for future frame for liveshot
7471         attr.post_frame_skip = mParameters.getZSLBurstInterval();
7472         attr.water_mark = 1; //hold min buffers possible in Q
7473         attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
7474         rc = pChannel->init(&attr, snapshot_channel_cb_routine, this);
7475     } else {
7476         // preview only channel, don't need bundle attr and cb
7477         rc = pChannel->init(NULL, NULL, NULL);
7478     }
7479 
7480     if (rc != 0) {
7481         LOGE("init video channel failed, ret = %d", rc);
7482         delete pChannel;
7483         return rc;
7484     }
7485 
7486     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_VIDEO,
7487             video_stream_cb_routine, this);
7488 
7489     if (rc != NO_ERROR) {
7490         LOGE("add video stream failed, ret = %d", rc);
7491         delete pChannel;
7492         return rc;
7493     }
7494 
7495     m_channels[QCAMERA_CH_TYPE_VIDEO] = pChannel;
7496     return rc;
7497 }
7498 
7499 /*===========================================================================
7500  * FUNCTION   : addSnapshotChannel
7501  *
7502  * DESCRIPTION: add a snapshot channel that contains a snapshot stream
7503  *
7504  * PARAMETERS : none
7505  *
7506  * RETURN     : int32_t type of status
7507  *              NO_ERROR  -- success
7508  *              none-zero failure code
7509  * NOTE       : Add this channel for live snapshot usecase. Regular capture will
7510  *              use addCaptureChannel.
7511  *==========================================================================*/
addSnapshotChannel()7512 int32_t QCamera2HardwareInterface::addSnapshotChannel()
7513 {
7514     int32_t rc = NO_ERROR;
7515     QCameraChannel *pChannel = NULL;
7516 
7517     if (m_channels[QCAMERA_CH_TYPE_SNAPSHOT] != NULL) {
7518         // if we had ZSL channel before, delete it first
7519         delete m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
7520         m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = NULL;
7521     }
7522 
7523     uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_SNAPSHOT);
7524     pChannel = new QCameraChannel(handle, mCameraHandle->ops);
7525     if (NULL == pChannel) {
7526         LOGE("no mem for snapshot channel");
7527         return NO_MEMORY;
7528     }
7529 
7530     mm_camera_channel_attr_t attr;
7531     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
7532     attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
7533     attr.look_back = 0; //wait for future frame for liveshot
7534     attr.post_frame_skip = mParameters.getZSLBurstInterval();
7535     attr.water_mark = 1; //hold min buffers possible in Q
7536     attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
7537     attr.priority = MM_CAMERA_SUPER_BUF_PRIORITY_LOW;
7538     rc = pChannel->init(&attr, snapshot_channel_cb_routine, this);
7539     if (rc != NO_ERROR) {
7540         LOGE("init snapshot channel failed, ret = %d", rc);
7541         delete pChannel;
7542         return rc;
7543     }
7544 
7545     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
7546             NULL, NULL);
7547     if (rc != NO_ERROR) {
7548         LOGE("add snapshot stream failed, ret = %d", rc);
7549         delete pChannel;
7550         return rc;
7551     }
7552 
7553     m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = pChannel;
7554     return rc;
7555 }
7556 
7557 /*===========================================================================
7558  * FUNCTION   : addRawChannel
7559  *
7560  * DESCRIPTION: add a raw channel that contains a raw image stream
7561  *
7562  * PARAMETERS : none
7563  *
7564  * RETURN     : int32_t type of status
7565  *              NO_ERROR  -- success
7566  *              none-zero failure code
7567  *==========================================================================*/
addRawChannel()7568 int32_t QCamera2HardwareInterface::addRawChannel()
7569 {
7570     int32_t rc = NO_ERROR;
7571     QCameraChannel *pChannel = NULL;
7572 
7573     if (m_channels[QCAMERA_CH_TYPE_RAW] != NULL) {
7574         // if we had raw channel before, delete it first
7575         delete m_channels[QCAMERA_CH_TYPE_RAW];
7576         m_channels[QCAMERA_CH_TYPE_RAW] = NULL;
7577     }
7578 
7579     uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_RAW);
7580     pChannel = new QCameraChannel(handle, mCameraHandle->ops);
7581     if (NULL == pChannel) {
7582         LOGE("no mem for raw channel");
7583         return NO_MEMORY;
7584     }
7585 
7586     if (mParameters.getofflineRAW()) {
7587         mm_camera_channel_attr_t attr;
7588         memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
7589         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
7590         attr.look_back = mParameters.getZSLBackLookCount();
7591         attr.post_frame_skip = mParameters.getZSLBurstInterval();
7592         attr.water_mark = 1;
7593         attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
7594         rc = pChannel->init(&attr, raw_channel_cb_routine, this);
7595         if (rc != NO_ERROR) {
7596             LOGE("init RAW channel failed, ret = %d", rc);
7597             delete pChannel;
7598             return rc;
7599         }
7600     } else {
7601         rc = pChannel->init(NULL, NULL, NULL);
7602         if (rc != NO_ERROR) {
7603             LOGE("init raw channel failed, ret = %d", rc);
7604             delete pChannel;
7605             return rc;
7606         }
7607     }
7608 
7609     if (!mParameters.isZSLMode()) {
7610         // meta data stream always coexists with snapshot in regular RAW capture case
7611         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
7612                 metadata_stream_cb_routine, this);
7613         if (rc != NO_ERROR) {
7614             LOGE("add metadata stream failed, ret = %d", rc);
7615             delete pChannel;
7616             return rc;
7617         }
7618     }
7619 
7620     if (mParameters.getofflineRAW()) {
7621         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
7622                 NULL, this);
7623     } else {
7624         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
7625                 raw_stream_cb_routine, this);
7626     }
7627     if (rc != NO_ERROR) {
7628         LOGE("add snapshot stream failed, ret = %d", rc);
7629         delete pChannel;
7630         return rc;
7631     }
7632     m_channels[QCAMERA_CH_TYPE_RAW] = pChannel;
7633     return rc;
7634 }
7635 
7636 /*===========================================================================
7637  * FUNCTION   : addZSLChannel
7638  *
7639  * DESCRIPTION: add a ZSL channel that contains a preview stream and
7640  *              a snapshot stream
7641  *
7642  * PARAMETERS : none
7643  *
7644  * RETURN     : int32_t type of status
7645  *              NO_ERROR  -- success
7646  *              none-zero failure code
7647  *==========================================================================*/
addZSLChannel()7648 int32_t QCamera2HardwareInterface::addZSLChannel()
7649 {
7650     int32_t rc = NO_ERROR;
7651     QCameraPicChannel *pChannel = NULL;
7652     char value[PROPERTY_VALUE_MAX];
7653     bool raw_yuv = false;
7654 
7655     if (m_channels[QCAMERA_CH_TYPE_ZSL] != NULL) {
7656         // if we had ZSL channel before, delete it first
7657         delete m_channels[QCAMERA_CH_TYPE_ZSL];
7658         m_channels[QCAMERA_CH_TYPE_ZSL] = NULL;
7659     }
7660 
7661     uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_ZSL);
7662     pChannel = new QCameraPicChannel(handle,
7663                                      mCameraHandle->ops);
7664     if (NULL == pChannel) {
7665         LOGE("no mem for ZSL channel");
7666         return NO_MEMORY;
7667     }
7668 
7669     // ZSL channel, init with bundle attr and cb
7670     mm_camera_channel_attr_t attr;
7671     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
7672     if (mParameters.isSceneSelectionEnabled()) {
7673         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
7674     } else {
7675         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
7676     }
7677     attr.look_back = mParameters.getZSLBackLookCount();
7678     attr.post_frame_skip = mParameters.getZSLBurstInterval();
7679     if (mParameters.isOEMFeatEnabled()) {
7680         attr.post_frame_skip++;
7681     }
7682     attr.water_mark = mParameters.getZSLQueueDepth();
7683     attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
7684     attr.user_expected_frame_id =
7685         mParameters.isInstantCaptureEnabled() ? (uint8_t)mParameters.getAecFrameBoundValue() : 0;
7686 
7687     //Enabled matched queue
7688     if (isFrameSyncEnabled()) {
7689         LOGH("Enabling frame sync for dual camera, camera Id: %d",
7690                  mCameraId);
7691         attr.enable_frame_sync = 1;
7692     }
7693     rc = pChannel->init(&attr,
7694                         zsl_channel_cb,
7695                         this);
7696     if (rc != 0) {
7697         LOGE("init ZSL channel failed, ret = %d", rc);
7698         delete pChannel;
7699         return rc;
7700     }
7701 
7702     // meta data stream always coexists with preview if applicable
7703     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
7704             metadata_stream_cb_routine, this);
7705     if (rc != NO_ERROR) {
7706         LOGE("add metadata stream failed, ret = %d", rc);
7707         delete pChannel;
7708         return rc;
7709     }
7710 
7711     if (isNoDisplayMode()) {
7712         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
7713                 nodisplay_preview_stream_cb_routine, this);
7714     } else {
7715         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
7716                 preview_stream_cb_routine, this);
7717         if (needSyncCB(CAM_STREAM_TYPE_PREVIEW) == TRUE) {
7718             pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
7719                     synchronous_stream_cb_routine);
7720         }
7721     }
7722     if (rc != NO_ERROR) {
7723         LOGE("add preview stream failed, ret = %d", rc);
7724         delete pChannel;
7725         return rc;
7726     }
7727 
7728     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
7729             NULL, this);
7730     if (rc != NO_ERROR) {
7731         LOGE("add snapshot stream failed, ret = %d", rc);
7732         delete pChannel;
7733         return rc;
7734     }
7735 
7736     if (!mParameters.isSecureMode()) {
7737         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
7738                 NULL, this);
7739         if (rc != NO_ERROR) {
7740             LOGE("add Analysis stream failed, ret = %d", rc);
7741             delete pChannel;
7742             return rc;
7743         }
7744     }
7745 
7746     property_get("persist.camera.raw_yuv", value, "0");
7747     raw_yuv = atoi(value) > 0 ? true : false;
7748     if (raw_yuv) {
7749         rc = addStreamToChannel(pChannel,
7750                                 CAM_STREAM_TYPE_RAW,
7751                                 preview_raw_stream_cb_routine,
7752                                 this);
7753         if (rc != NO_ERROR) {
7754             LOGE("add raw stream failed, ret = %d", rc);
7755             delete pChannel;
7756             return rc;
7757         }
7758     }
7759 
7760     m_channels[QCAMERA_CH_TYPE_ZSL] = pChannel;
7761     return rc;
7762 }
7763 
7764 /*===========================================================================
7765  * FUNCTION   : addCaptureChannel
7766  *
7767  * DESCRIPTION: add a capture channel that contains a snapshot stream
7768  *              and a postview stream
7769  *
7770  * PARAMETERS : none
7771  *
7772  * RETURN     : int32_t type of status
7773  *              NO_ERROR  -- success
7774  *              none-zero failure code
7775  * NOTE       : Add this channel for regular capture usecase.
7776  *              For Live snapshot usecase, use addSnapshotChannel.
7777  *==========================================================================*/
addCaptureChannel()7778 int32_t QCamera2HardwareInterface::addCaptureChannel()
7779 {
7780     int32_t rc = NO_ERROR;
7781     QCameraPicChannel *pChannel = NULL;
7782     char value[PROPERTY_VALUE_MAX];
7783     bool raw_yuv = false;
7784 
7785     if (m_channels[QCAMERA_CH_TYPE_CAPTURE] != NULL) {
7786         delete m_channels[QCAMERA_CH_TYPE_CAPTURE];
7787         m_channels[QCAMERA_CH_TYPE_CAPTURE] = NULL;
7788     }
7789 
7790     uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_CAPTURE);
7791     pChannel = new QCameraPicChannel(handle, mCameraHandle->ops);
7792     if (NULL == pChannel) {
7793         LOGE("no mem for capture channel");
7794         return NO_MEMORY;
7795     }
7796 
7797     // Capture channel, only need snapshot and postview streams start together
7798     mm_camera_channel_attr_t attr;
7799     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
7800     if ( mLongshotEnabled ) {
7801         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
7802         attr.look_back = mParameters.getZSLBackLookCount();
7803         attr.water_mark = mParameters.getZSLQueueDepth();
7804     } else {
7805         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
7806     }
7807     attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
7808 
7809     rc = pChannel->init(&attr,
7810                         capture_channel_cb_routine,
7811                         this);
7812     if (rc != NO_ERROR) {
7813         LOGE("init capture channel failed, ret = %d", rc);
7814         delete pChannel;
7815         return rc;
7816     }
7817 
7818     // meta data stream always coexists with snapshot in regular capture case
7819     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
7820             metadata_stream_cb_routine, this);
7821     if (rc != NO_ERROR) {
7822         LOGE("add metadata stream failed, ret = %d", rc);
7823         delete pChannel;
7824         return rc;
7825     }
7826 
7827     if (mLongshotEnabled) {
7828         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
7829                 preview_stream_cb_routine, this);
7830         if (rc != NO_ERROR) {
7831             LOGE("add preview stream failed, ret = %d", rc);
7832             delete pChannel;
7833             return rc;
7834         }
7835         if (needSyncCB(CAM_STREAM_TYPE_PREVIEW) == TRUE) {
7836             pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
7837                     synchronous_stream_cb_routine);
7838         }
7839     //Not adding the postview stream to the capture channel if Quadra CFA is enabled.
7840     } else if (!mParameters.getQuadraCfa()) {
7841         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_POSTVIEW,
7842                                 NULL, this);
7843         if (rc != NO_ERROR) {
7844             LOGE("add postview stream failed, ret = %d", rc);
7845             delete pChannel;
7846             return rc;
7847         }
7848     }
7849 
7850     if (!mParameters.getofflineRAW()) {
7851         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
7852                 NULL, this);
7853         if (rc != NO_ERROR) {
7854             LOGE("add snapshot stream failed, ret = %d", rc);
7855             delete pChannel;
7856             return rc;
7857         }
7858     }
7859 
7860     stream_cb_routine stream_cb = NULL;
7861     property_get("persist.camera.raw_yuv", value, "0");
7862     raw_yuv = atoi(value) > 0 ? true : false;
7863 
7864     if (raw_yuv) {
7865         stream_cb = snapshot_raw_stream_cb_routine;
7866     }
7867 
7868     if ((raw_yuv) || (mParameters.getofflineRAW())) {
7869         rc = addStreamToChannel(pChannel,
7870                 CAM_STREAM_TYPE_RAW, stream_cb, this);
7871         if (rc != NO_ERROR) {
7872             LOGE("add raw stream failed, ret = %d", rc);
7873             delete pChannel;
7874             return rc;
7875         }
7876     }
7877 
7878     m_channels[QCAMERA_CH_TYPE_CAPTURE] = pChannel;
7879     return rc;
7880 }
7881 
7882 /*===========================================================================
7883  * FUNCTION   : addMetaDataChannel
7884  *
7885  * DESCRIPTION: add a meta data channel that contains a metadata stream
7886  *
7887  * PARAMETERS : none
7888  *
7889  * RETURN     : int32_t type of status
7890  *              NO_ERROR  -- success
7891  *              none-zero failure code
7892  *==========================================================================*/
addMetaDataChannel()7893 int32_t QCamera2HardwareInterface::addMetaDataChannel()
7894 {
7895     int32_t rc = NO_ERROR;
7896     QCameraChannel *pChannel = NULL;
7897 
7898     if (m_channels[QCAMERA_CH_TYPE_METADATA] != NULL) {
7899         delete m_channels[QCAMERA_CH_TYPE_METADATA];
7900         m_channels[QCAMERA_CH_TYPE_METADATA] = NULL;
7901     }
7902 
7903     uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_METADATA);
7904     pChannel = new QCameraChannel(handle, mCameraHandle->ops);
7905     if (NULL == pChannel) {
7906         LOGE("no mem for metadata channel");
7907         return NO_MEMORY;
7908     }
7909 
7910     rc = pChannel->init(NULL,
7911                         NULL,
7912                         NULL);
7913     if (rc != NO_ERROR) {
7914         LOGE("init metadata channel failed, ret = %d", rc);
7915         delete pChannel;
7916         return rc;
7917     }
7918 
7919     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
7920             metadata_stream_cb_routine, this);
7921     if (rc != NO_ERROR) {
7922         LOGE("add metadata stream failed, ret = %d", rc);
7923         delete pChannel;
7924         return rc;
7925     }
7926 
7927     m_channels[QCAMERA_CH_TYPE_METADATA] = pChannel;
7928     return rc;
7929 }
7930 
7931 /*===========================================================================
7932  * FUNCTION   : addCallbackChannel
7933  *
7934  * DESCRIPTION: add a callback channel that contains a callback stream
7935  *
7936  * PARAMETERS : none
7937  *
7938  * RETURN     : int32_t type of status
7939  *              NO_ERROR  -- success
7940  *              none-zero failure code
7941  *==========================================================================*/
addCallbackChannel()7942 int32_t QCamera2HardwareInterface::addCallbackChannel()
7943 {
7944     int32_t rc = NO_ERROR;
7945     QCameraChannel *pChannel = NULL;
7946 
7947     if (m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL) {
7948         delete m_channels[QCAMERA_CH_TYPE_CALLBACK];
7949         m_channels[QCAMERA_CH_TYPE_CALLBACK] = NULL;
7950     }
7951 
7952     uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_CALLBACK);
7953     pChannel = new QCameraChannel(handle, mCameraHandle->ops);
7954     if (NULL == pChannel) {
7955         LOGE("no mem for callback channel");
7956         return NO_MEMORY;
7957     }
7958 
7959     rc = pChannel->init(NULL, NULL, this);
7960     if (rc != NO_ERROR) {
7961         LOGE("init callback channel failed, ret = %d",
7962                  rc);
7963         delete pChannel;
7964         return rc;
7965     }
7966 
7967     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_CALLBACK,
7968             callback_stream_cb_routine, this);
7969     if (rc != NO_ERROR) {
7970         LOGE("add callback stream failed, ret = %d", rc);
7971         delete pChannel;
7972         return rc;
7973     }
7974 
7975     m_channels[QCAMERA_CH_TYPE_CALLBACK] = pChannel;
7976     return rc;
7977 }
7978 
7979 
7980 /*===========================================================================
7981  * FUNCTION   : addAnalysisChannel
7982  *
7983  * DESCRIPTION: add a analysis channel that contains a analysis stream
7984  *
7985  * PARAMETERS : none
7986  *
7987  * RETURN     : int32_t type of status
7988  *              NO_ERROR  -- success
7989  *              none-zero failure code
7990  *==========================================================================*/
addAnalysisChannel()7991 int32_t QCamera2HardwareInterface::addAnalysisChannel()
7992 {
7993     int32_t rc = NO_ERROR;
7994     QCameraChannel *pChannel = NULL;
7995 
7996     if (m_channels[QCAMERA_CH_TYPE_ANALYSIS] != NULL) {
7997         delete m_channels[QCAMERA_CH_TYPE_ANALYSIS];
7998         m_channels[QCAMERA_CH_TYPE_ANALYSIS] = NULL;
7999     }
8000 
8001     uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_ANALYSIS);
8002     pChannel = new QCameraChannel(handle, mCameraHandle->ops);
8003     if (NULL == pChannel) {
8004         LOGE("no mem for metadata channel");
8005         return NO_MEMORY;
8006     }
8007 
8008     rc = pChannel->init(NULL, NULL, this);
8009     if (rc != NO_ERROR) {
8010         LOGE("init Analysis channel failed, ret = %d", rc);
8011         delete pChannel;
8012         return rc;
8013     }
8014 
8015     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
8016             NULL, this);
8017     if (rc != NO_ERROR) {
8018         LOGE("add Analysis stream failed, ret = %d", rc);
8019         delete pChannel;
8020         return rc;
8021     }
8022 
8023     m_channels[QCAMERA_CH_TYPE_ANALYSIS] = pChannel;
8024     return rc;
8025 }
8026 
8027 
8028 /*===========================================================================
8029  * FUNCTION   : getPPConfig
8030  *
8031  * DESCRIPTION: get Post processing configaration data
8032  *
8033  * PARAMETERS :
8034  * @pp config:  pp config structure pointer,
8035  * @curIndex:  current pp channel index
8036  * @multipass: Flag if multipass prcessing enabled.
8037  *
8038  * RETURN     : int32_t type of status
8039  *              NO_ERROR  -- success
8040  *              none-zero failure code
8041  *==========================================================================*/
getPPConfig(cam_pp_feature_config_t & pp_config,int8_t curIndex,bool multipass)8042 int32_t QCamera2HardwareInterface::getPPConfig(cam_pp_feature_config_t &pp_config,
8043         int8_t curIndex, bool multipass)
8044 {
8045     int32_t rc = NO_ERROR;
8046     int32_t feature_set = 0;
8047 
8048     if (multipass) {
8049         LOGW("Multi pass enabled. Total Pass = %d, cur index = %d",
8050                 mParameters.getReprocCount(), curIndex);
8051     }
8052 
8053     LOGH("Supported pproc feature mask = %llx",
8054             gCamCapability[mCameraId]->qcom_supported_feature_mask);
8055     cam_feature_mask_t feature_mask = gCamCapability[mCameraId]->qcom_supported_feature_mask;
8056     int32_t zoomLevel = mParameters.getParmZoomLevel();
8057     uint32_t rotation = mParameters.getJpegRotation();
8058     int32_t effect = mParameters.getEffectValue();
8059 
8060     pp_config.cur_reproc_count = curIndex + 1;
8061     pp_config.total_reproc_count = mParameters.getReprocCount();
8062 
8063     //Checking what feature mask to enable
8064     if (curIndex == 0) {
8065         if (mParameters.getQuadraCfa()) {
8066             feature_set = 2;
8067         } else {
8068             feature_set = 0;
8069         }
8070     } else if (curIndex == 1) {
8071         if (mParameters.getQuadraCfa()) {
8072             feature_set = 0;
8073         } else {
8074             feature_set = 1;
8075         }
8076     }
8077 
8078     switch(feature_set) {
8079         case 0:
8080             //Configure feature mask for first pass of reprocessing
8081             //check if any effects are enabled
8082             if ((CAM_EFFECT_MODE_OFF != effect) &&
8083                 (feature_mask & CAM_QCOM_FEATURE_EFFECT)) {
8084                 pp_config.feature_mask |= CAM_QCOM_FEATURE_EFFECT;
8085                 pp_config.effect = effect;
8086             }
8087 
8088             //check for features that need to be enabled by default like sharpness
8089             //(if supported by hw).
8090             if ((feature_mask & CAM_QCOM_FEATURE_SHARPNESS) &&
8091                 !mParameters.isOptiZoomEnabled()) {
8092                 pp_config.feature_mask |= CAM_QCOM_FEATURE_SHARPNESS;
8093                 pp_config.sharpness = mParameters.getSharpness();
8094             }
8095 
8096             //check if zoom is enabled
8097             if ((zoomLevel > 0) && (feature_mask & CAM_QCOM_FEATURE_CROP)) {
8098                 pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
8099             }
8100 
8101             if (mParameters.isWNREnabled() &&
8102                 (feature_mask & CAM_QCOM_FEATURE_DENOISE2D)) {
8103                 pp_config.feature_mask |= CAM_QCOM_FEATURE_DENOISE2D;
8104                 pp_config.denoise2d.denoise_enable = 1;
8105                 pp_config.denoise2d.process_plates =
8106                         mParameters.getDenoiseProcessPlate(CAM_INTF_PARM_WAVELET_DENOISE);
8107             }
8108 
8109             if (isCACEnabled()) {
8110                 pp_config.feature_mask |= CAM_QCOM_FEATURE_CAC;
8111             }
8112 
8113             //check if rotation is required
8114             if ((feature_mask & CAM_QCOM_FEATURE_ROTATION) && (rotation > 0)) {
8115                 pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION;
8116                 if (rotation == 0) {
8117                     pp_config.rotation = ROTATE_0;
8118                 } else if (rotation == 90) {
8119                     pp_config.rotation = ROTATE_90;
8120                 } else if (rotation == 180) {
8121                     pp_config.rotation = ROTATE_180;
8122                 } else if (rotation == 270) {
8123                     pp_config.rotation = ROTATE_270;
8124                 }
8125             }
8126 
8127             if (mParameters.isHDREnabled()){
8128                 pp_config.feature_mask |= CAM_QCOM_FEATURE_HDR;
8129                 pp_config.hdr_param.hdr_enable = 1;
8130                 pp_config.hdr_param.hdr_need_1x = mParameters.isHDR1xFrameEnabled();
8131                 pp_config.hdr_param.hdr_mode = CAM_HDR_MODE_MULTIFRAME;
8132             } else {
8133                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_HDR;
8134                 pp_config.hdr_param.hdr_enable = 0;
8135             }
8136 
8137             //check if scaling is enabled
8138             if ((feature_mask & CAM_QCOM_FEATURE_SCALE) &&
8139                 mParameters.isReprocScaleEnabled() &&
8140                 mParameters.isUnderReprocScaling()){
8141                 pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
8142                 mParameters.getPicSizeFromAPK(
8143                         pp_config.scale_param.output_width,
8144                         pp_config.scale_param.output_height);
8145             }
8146 
8147             if(mParameters.isUbiFocusEnabled()) {
8148                 pp_config.feature_mask |= CAM_QCOM_FEATURE_UBIFOCUS;
8149             } else {
8150                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_UBIFOCUS;
8151             }
8152 
8153             if(mParameters.isUbiRefocus()) {
8154                 pp_config.feature_mask |= CAM_QCOM_FEATURE_REFOCUS;
8155                 pp_config.misc_buf_param.misc_buffer_index = 0;
8156             } else {
8157                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_REFOCUS;
8158             }
8159 
8160             if(mParameters.isChromaFlashEnabled()) {
8161                 pp_config.feature_mask |= CAM_QCOM_FEATURE_CHROMA_FLASH;
8162                 pp_config.flash_value = CAM_FLASH_ON;
8163             } else {
8164                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_CHROMA_FLASH;
8165             }
8166 
8167             if(mParameters.isOptiZoomEnabled() && (0 <= zoomLevel)) {
8168                 pp_config.feature_mask |= CAM_QCOM_FEATURE_OPTIZOOM;
8169                 pp_config.zoom_level = (uint8_t) zoomLevel;
8170             } else {
8171                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_OPTIZOOM;
8172             }
8173 
8174             if (mParameters.getofflineRAW()) {
8175                 pp_config.feature_mask |= CAM_QCOM_FEATURE_RAW_PROCESSING;
8176             }
8177 
8178             if (mParameters.isTruePortraitEnabled()) {
8179                 pp_config.feature_mask |= CAM_QCOM_FEATURE_TRUEPORTRAIT;
8180                 pp_config.misc_buf_param.misc_buffer_index = 0;
8181             } else {
8182                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_TRUEPORTRAIT;
8183             }
8184 
8185             if(mParameters.isStillMoreEnabled()) {
8186                 pp_config.feature_mask |= CAM_QCOM_FEATURE_STILLMORE;
8187             } else {
8188                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_STILLMORE;
8189             }
8190 
8191             if (mParameters.isOEMFeatEnabled()) {
8192                 pp_config.feature_mask |= CAM_OEM_FEATURE_1;
8193             }
8194 
8195             if (mParameters.getCDSMode() != CAM_CDS_MODE_OFF) {
8196                 if (feature_mask & CAM_QCOM_FEATURE_DSDN) {
8197                     pp_config.feature_mask |= CAM_QCOM_FEATURE_DSDN;
8198                 } else {
8199                     pp_config.feature_mask |= CAM_QCOM_FEATURE_CDS;
8200                 }
8201             }
8202 
8203             if ((multipass) &&
8204                     (m_postprocessor.getPPChannelCount() > 1)
8205                     && (!mParameters.getQuadraCfa())) {
8206                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_PP_PASS_2;
8207                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_ROTATION;
8208                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_CDS;
8209                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_DSDN;
8210                 pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
8211             } else {
8212                 pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
8213             }
8214 
8215             cam_dimension_t thumb_src_dim;
8216             cam_dimension_t thumb_dst_dim;
8217             mParameters.getThumbnailSize(&(thumb_dst_dim.width), &(thumb_dst_dim.height));
8218             mParameters.getStreamDimension(CAM_STREAM_TYPE_POSTVIEW,thumb_src_dim);
8219             if ((thumb_dst_dim.width != thumb_src_dim.width) ||
8220                     (thumb_dst_dim.height != thumb_src_dim.height)) {
8221                 if (thumb_dst_dim.width != 0 && thumb_dst_dim.height != 0) {
8222                     pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
8223                 }
8224             }
8225 
8226             break;
8227 
8228         case 1:
8229             //Configure feature mask for second pass of reprocessing
8230             pp_config.feature_mask |= CAM_QCOM_FEATURE_PP_PASS_2;
8231             if ((feature_mask & CAM_QCOM_FEATURE_ROTATION) && (rotation > 0)) {
8232                 pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION;
8233                 if (rotation == 0) {
8234                     pp_config.rotation = ROTATE_0;
8235                 } else if (rotation == 90) {
8236                     pp_config.rotation = ROTATE_90;
8237                 } else if (rotation == 180) {
8238                     pp_config.rotation = ROTATE_180;
8239                 } else if (rotation == 270) {
8240                     pp_config.rotation = ROTATE_270;
8241                 }
8242             }
8243             if (mParameters.getCDSMode() != CAM_CDS_MODE_OFF) {
8244                 if (feature_mask & CAM_QCOM_FEATURE_DSDN) {
8245                     pp_config.feature_mask |= CAM_QCOM_FEATURE_DSDN;
8246                 } else {
8247                     pp_config.feature_mask |= CAM_QCOM_FEATURE_CDS;
8248                 }
8249             }
8250             pp_config.feature_mask &= ~CAM_QCOM_FEATURE_RAW_PROCESSING;
8251             pp_config.feature_mask &= ~CAM_QCOM_FEATURE_METADATA_PROCESSING;
8252             pp_config.feature_mask &= ~CAM_QCOM_FEATURE_METADATA_BYPASS;
8253             break;
8254 
8255         case 2:
8256             //Setting feature for Quadra CFA
8257             pp_config.feature_mask |= CAM_QCOM_FEATURE_QUADRA_CFA;
8258             break;
8259 
8260     }
8261 
8262     LOGH("pproc feature mask set = %llx pass count = %d",
8263         pp_config.feature_mask, curIndex);
8264     return rc;
8265 }
8266 
8267 /*===========================================================================
8268  * FUNCTION   : addReprocChannel
8269  *
8270  * DESCRIPTION: add a reprocess channel that will do reprocess on frames
8271  *              coming from input channel
8272  *
8273  * PARAMETERS :
8274  *   @pInputChannel : ptr to input channel whose frames will be post-processed
8275  *   @cur_channel_index : Current channel index in multipass
8276  *
8277  * RETURN     : Ptr to the newly created channel obj. NULL if failed.
8278  *==========================================================================*/
addReprocChannel(QCameraChannel * pInputChannel,int8_t cur_channel_index)8279 QCameraReprocessChannel *QCamera2HardwareInterface::addReprocChannel(
8280         QCameraChannel *pInputChannel, int8_t cur_channel_index)
8281 {
8282     int32_t rc = NO_ERROR;
8283     QCameraReprocessChannel *pChannel = NULL;
8284     uint32_t burst_cnt = mParameters.getNumOfSnapshots();
8285     uint32_t pHandle = getCamHandleForChannel(QCAMERA_CH_TYPE_REPROCESSING);
8286 
8287     if (pInputChannel == NULL) {
8288         LOGE("input channel obj is NULL");
8289         return NULL;
8290     }
8291 
8292     pChannel = new QCameraReprocessChannel(pHandle, mCameraHandle->ops);
8293     if (NULL == pChannel) {
8294         LOGE("no mem for reprocess channel");
8295         return NULL;
8296     }
8297 
8298     // Capture channel, only need snapshot and postview streams start together
8299     mm_camera_channel_attr_t attr;
8300     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
8301     attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
8302     attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
8303     rc = pChannel->init(&attr,
8304                         postproc_channel_cb_routine,
8305                         this);
8306     if (rc != NO_ERROR) {
8307         LOGE("init reprocess channel failed, ret = %d", rc);
8308         delete pChannel;
8309         return NULL;
8310     }
8311 
8312     // pp feature config
8313     cam_pp_feature_config_t pp_config;
8314     memset(&pp_config, 0, sizeof(cam_pp_feature_config_t));
8315 
8316     rc = getPPConfig(pp_config, cur_channel_index,
8317             ((mParameters.getReprocCount() > 1) ? TRUE : FALSE));
8318     if (rc != NO_ERROR){
8319         LOGE("Error while creating PP config");
8320         delete pChannel;
8321         return NULL;
8322     }
8323 
8324     uint8_t minStreamBufNum = getBufNumRequired(CAM_STREAM_TYPE_OFFLINE_PROC);
8325 
8326     //WNR and HDR happen inline. No extra buffers needed.
8327     cam_feature_mask_t temp_feature_mask = pp_config.feature_mask;
8328     temp_feature_mask &= ~CAM_QCOM_FEATURE_HDR;
8329     if (temp_feature_mask && mParameters.isHDREnabled()) {
8330         minStreamBufNum = (uint8_t)(1 + mParameters.getNumOfExtraHDRInBufsIfNeeded());
8331     }
8332 
8333     if (mParameters.isStillMoreEnabled()) {
8334         cam_still_more_t stillmore_config = mParameters.getStillMoreSettings();
8335         pp_config.burst_cnt = stillmore_config.burst_count;
8336         LOGH("Stillmore burst %d", pp_config.burst_cnt);
8337 
8338         // getNumOfExtraBuffersForImageProc returns 1 less buffer assuming
8339         // number of capture is already added. In the case of liveshot,
8340         // stillmore burst is 1. This is to account for the premature decrement
8341         if (mParameters.getNumOfExtraBuffersForImageProc() == 0) {
8342             minStreamBufNum += 1;
8343         }
8344     }
8345 
8346     if (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_3) {
8347         minStreamBufNum += mParameters.getReprocCount() - 1;
8348         burst_cnt = mParameters.getReprocCount();
8349         if (cur_channel_index == 0) {
8350             pChannel->setReprocCount(2);
8351         } else {
8352             pChannel->setReprocCount(1);
8353         }
8354     } else {
8355         pChannel->setReprocCount(1);
8356     }
8357 
8358     if (isDualCamera()) {
8359         minStreamBufNum += 1;
8360     }
8361 
8362     // Add non inplace image lib buffers only when ppproc is present,
8363     // becuase pproc is non inplace and input buffers for img lib
8364     // are output for pproc and this number of extra buffers is required
8365     // If pproc is not there, input buffers for imglib are from snapshot stream
8366     uint8_t imglib_extra_bufs = mParameters.getNumOfExtraBuffersForImageProc();
8367     if (temp_feature_mask && imglib_extra_bufs) {
8368         // 1 is added because getNumOfExtraBuffersForImageProc returns extra
8369         // buffers assuming number of capture is already added
8370         minStreamBufNum = (uint8_t)(minStreamBufNum + imglib_extra_bufs + 1);
8371     }
8372 
8373     //Mask out features that are already processed in snapshot stream.
8374     cam_feature_mask_t snapshot_feature_mask = 0;
8375     mParameters.getStreamPpMask(CAM_STREAM_TYPE_SNAPSHOT, snapshot_feature_mask);
8376 
8377     pp_config.feature_mask &= ~snapshot_feature_mask;
8378     LOGH("Snapshot feature mask: 0x%llx, reproc feature mask: 0x%llx minStreamBufNum = %d",
8379             snapshot_feature_mask, pp_config.feature_mask, minStreamBufNum);
8380 
8381     bool offlineReproc = needOfflineReprocessing();
8382     if (m_postprocessor.mOfflineDataBufs != NULL) {
8383         offlineReproc = TRUE;
8384     }
8385 
8386     cam_padding_info_t paddingInfo = gCamCapability[mCameraId]->padding_info;
8387     paddingInfo.offset_info.offset_x = 0;
8388     paddingInfo.offset_info.offset_y = 0;
8389     rc = pChannel->addReprocStreamsFromSource(*this,
8390                                               pp_config,
8391                                               pInputChannel,
8392                                               minStreamBufNum,
8393                                               burst_cnt,
8394                                               &paddingInfo,
8395                                               mParameters,
8396                                               mLongshotEnabled,
8397                                               offlineReproc);
8398     if (rc != NO_ERROR) {
8399         delete pChannel;
8400         return NULL;
8401     }
8402 
8403     return pChannel;
8404 }
8405 
8406 /*===========================================================================
8407  * FUNCTION   : addOfflineReprocChannel
8408  *
8409  * DESCRIPTION: add a offline reprocess channel contains one reproc stream,
8410  *              that will do reprocess on frames coming from external images
8411  *
8412  * PARAMETERS :
8413  *   @img_config  : offline reporcess image info
8414  *   @pp_feature  : pp feature config
8415  *
8416  * RETURN     : int32_t type of status
8417  *              NO_ERROR  -- success
8418  *              none-zero failure code
8419  *==========================================================================*/
addOfflineReprocChannel(cam_pp_offline_src_config_t & img_config,cam_pp_feature_config_t & pp_feature,stream_cb_routine stream_cb,void * userdata)8420 QCameraReprocessChannel *QCamera2HardwareInterface::addOfflineReprocChannel(
8421                                             cam_pp_offline_src_config_t &img_config,
8422                                             cam_pp_feature_config_t &pp_feature,
8423                                             stream_cb_routine stream_cb,
8424                                             void *userdata)
8425 {
8426     int32_t rc = NO_ERROR;
8427     QCameraReprocessChannel *pChannel = NULL;
8428 
8429     pChannel = new QCameraReprocessChannel(mCameraHandle->camera_handle,
8430                                            mCameraHandle->ops);
8431     if (NULL == pChannel) {
8432         LOGE("no mem for reprocess channel");
8433         return NULL;
8434     }
8435 
8436     rc = pChannel->init(NULL, NULL, NULL);
8437     if (rc != NO_ERROR) {
8438         LOGE("init reprocess channel failed, ret = %d", rc);
8439         delete pChannel;
8440         return NULL;
8441     }
8442 
8443     QCameraHeapMemory *pStreamInfo = allocateStreamInfoBuf(CAM_STREAM_TYPE_OFFLINE_PROC);
8444     if (pStreamInfo == NULL) {
8445         LOGE("no mem for stream info buf");
8446         delete pChannel;
8447         return NULL;
8448     }
8449 
8450     cam_stream_info_t *streamInfoBuf = (cam_stream_info_t *)pStreamInfo->getPtr(0);
8451     memset(streamInfoBuf, 0, sizeof(cam_stream_info_t));
8452     streamInfoBuf->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC;
8453     streamInfoBuf->fmt = img_config.input_fmt;
8454     streamInfoBuf->dim = img_config.input_dim;
8455     streamInfoBuf->buf_planes = img_config.input_buf_planes;
8456     streamInfoBuf->streaming_mode = CAM_STREAMING_MODE_BURST;
8457     streamInfoBuf->num_of_burst = img_config.num_of_bufs;
8458 
8459     streamInfoBuf->reprocess_config.pp_type = CAM_OFFLINE_REPROCESS_TYPE;
8460     streamInfoBuf->reprocess_config.offline = img_config;
8461     streamInfoBuf->reprocess_config.pp_feature_config = pp_feature;
8462     streamInfoBuf->num_bufs = img_config.num_of_bufs;
8463 
8464     rc = pChannel->addStream(*this,
8465             pStreamInfo, NULL,
8466             &gCamCapability[mCameraId]->padding_info,
8467             stream_cb, userdata, false);
8468 
8469     if (rc != NO_ERROR) {
8470         LOGE("add reprocess stream failed, ret = %d", rc);
8471         delete pChannel;
8472         return NULL;
8473     }
8474 
8475     return pChannel;
8476 }
8477 
8478 /*===========================================================================
8479  * FUNCTION   : addChannel
8480  *
8481  * DESCRIPTION: add a channel by its type
8482  *
8483  * PARAMETERS :
8484  *   @ch_type : channel type
8485  *
8486  * RETURN     : int32_t type of status
8487  *              NO_ERROR  -- success
8488  *              none-zero failure code
8489  *==========================================================================*/
addChannel(qcamera_ch_type_enum_t ch_type)8490 int32_t QCamera2HardwareInterface::addChannel(qcamera_ch_type_enum_t ch_type)
8491 {
8492     int32_t rc = UNKNOWN_ERROR;
8493     switch (ch_type) {
8494     case QCAMERA_CH_TYPE_ZSL:
8495         rc = addZSLChannel();
8496         break;
8497     case QCAMERA_CH_TYPE_CAPTURE:
8498         rc = addCaptureChannel();
8499         break;
8500     case QCAMERA_CH_TYPE_PREVIEW:
8501         rc = addPreviewChannel();
8502         break;
8503     case QCAMERA_CH_TYPE_VIDEO:
8504         rc = addVideoChannel();
8505         break;
8506     case QCAMERA_CH_TYPE_SNAPSHOT:
8507         rc = addSnapshotChannel();
8508         break;
8509     case QCAMERA_CH_TYPE_RAW:
8510         rc = addRawChannel();
8511         break;
8512     case QCAMERA_CH_TYPE_METADATA:
8513         rc = addMetaDataChannel();
8514         break;
8515     case QCAMERA_CH_TYPE_CALLBACK:
8516         rc = addCallbackChannel();
8517         break;
8518     case QCAMERA_CH_TYPE_ANALYSIS:
8519         rc = addAnalysisChannel();
8520         break;
8521     default:
8522         break;
8523     }
8524     return rc;
8525 }
8526 
8527 /*===========================================================================
8528  * FUNCTION   : delChannel
8529  *
8530  * DESCRIPTION: delete a channel by its type
8531  *
8532  * PARAMETERS :
8533  *   @ch_type : channel type
8534  *   @destroy : delete context as well
8535  *
8536  * RETURN     : int32_t type of status
8537  *              NO_ERROR  -- success
8538  *              none-zero failure code
8539  *==========================================================================*/
delChannel(qcamera_ch_type_enum_t ch_type,bool destroy)8540 int32_t QCamera2HardwareInterface::delChannel(qcamera_ch_type_enum_t ch_type,
8541                                               bool destroy)
8542 {
8543     if (m_channels[ch_type] != NULL) {
8544         if (destroy) {
8545             delete m_channels[ch_type];
8546             m_channels[ch_type] = NULL;
8547         } else {
8548             m_channels[ch_type]->deleteChannel();
8549         }
8550     }
8551 
8552     return NO_ERROR;
8553 }
8554 
8555 /*===========================================================================
8556  * FUNCTION   : startChannel
8557  *
8558  * DESCRIPTION: start a channel by its type
8559  *
8560  * PARAMETERS :
8561  *   @ch_type : channel type
8562  *
8563  * RETURN     : int32_t type of status
8564  *              NO_ERROR  -- success
8565  *              none-zero failure code
8566  *==========================================================================*/
startChannel(qcamera_ch_type_enum_t ch_type)8567 int32_t QCamera2HardwareInterface::startChannel(qcamera_ch_type_enum_t ch_type)
8568 {
8569     int32_t rc = UNKNOWN_ERROR;
8570     if (m_channels[ch_type] != NULL) {
8571         rc = m_channels[ch_type]->start();
8572     }
8573     return rc;
8574 }
8575 
8576 /*===========================================================================
8577  * FUNCTION   : stopChannel
8578  *
8579  * DESCRIPTION: stop a channel by its type
8580  *
8581  * PARAMETERS :
8582  *   @ch_type : channel type
8583  *
8584  * RETURN     : int32_t type of status
8585  *              NO_ERROR  -- success
8586  *              none-zero failure code
8587  *==========================================================================*/
stopChannel(qcamera_ch_type_enum_t ch_type)8588 int32_t QCamera2HardwareInterface::stopChannel(qcamera_ch_type_enum_t ch_type)
8589 {
8590     int32_t rc = UNKNOWN_ERROR;
8591     if (m_channels[ch_type] != NULL) {
8592         rc = m_channels[ch_type]->stop();
8593     }
8594 
8595     return rc;
8596 }
8597 
8598 /*===========================================================================
8599  * FUNCTION   : preparePreview
8600  *
8601  * DESCRIPTION: add channels needed for preview
8602  *
8603  * PARAMETERS : none
8604  *
8605  * RETURN     : int32_t type of status
8606  *              NO_ERROR  -- success
8607  *              none-zero failure code
8608  *==========================================================================*/
preparePreview()8609 int32_t QCamera2HardwareInterface::preparePreview()
8610 {
8611     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PREPAREPREVIEW);
8612     int32_t rc = NO_ERROR;
8613 
8614     LOGI("E");
8615     rc = mParameters.setStreamConfigure(false, false, false);
8616     if (rc != NO_ERROR) {
8617         LOGE("setStreamConfigure failed %d", rc);
8618         return rc;
8619     }
8620 
8621     if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) {
8622         rc = addChannel(QCAMERA_CH_TYPE_ZSL);
8623         if (rc != NO_ERROR) {
8624             LOGE("failed!! rc = %d", rc);
8625             return rc;
8626         }
8627 
8628         if (mParameters.isUBWCEnabled()) {
8629             cam_format_t fmt;
8630             mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW, fmt);
8631             if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
8632                 rc = addChannel(QCAMERA_CH_TYPE_CALLBACK);
8633                 if (rc != NO_ERROR) {
8634                     delChannel(QCAMERA_CH_TYPE_ZSL);
8635                     LOGE("failed!! rc = %d", rc);
8636                     return rc;
8637                 }
8638             }
8639         }
8640 
8641         if (mParameters.getofflineRAW() && !mParameters.getQuadraCfa()) {
8642             addChannel(QCAMERA_CH_TYPE_RAW);
8643         }
8644     } else {
8645         bool recordingHint = mParameters.getRecordingHintValue();
8646         if(!isRdiMode() && recordingHint) {
8647             //stop face detection,longshot,etc if turned ON in Camera mode
8648 #ifndef VANILLA_HAL
8649             int32_t arg; //dummy arg
8650             if (isLongshotEnabled()) {
8651                 sendCommand(CAMERA_CMD_LONGSHOT_OFF, arg, arg);
8652             }
8653             if (mParameters.isFaceDetectionEnabled()
8654                     && (!mParameters.fdModeInVideo())) {
8655                 sendCommand(CAMERA_CMD_STOP_FACE_DETECTION, arg, arg);
8656             }
8657             if (mParameters.isHistogramEnabled()) {
8658                 sendCommand(CAMERA_CMD_HISTOGRAM_OFF, arg, arg);
8659             }
8660 #endif
8661             //Don't create snapshot channel for liveshot, if low power mode is set.
8662             //Use video stream instead.
8663             if (!isLowPowerMode()) {
8664                rc = addChannel(QCAMERA_CH_TYPE_SNAPSHOT);
8665                if (rc != NO_ERROR) {
8666                    return rc;
8667                }
8668             }
8669 
8670             rc = addChannel(QCAMERA_CH_TYPE_VIDEO);
8671             if (rc != NO_ERROR) {
8672                 delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
8673                 LOGE("failed!! rc = %d", rc);
8674                 return rc;
8675             }
8676         }
8677 
8678         rc = addChannel(QCAMERA_CH_TYPE_PREVIEW);
8679         if (!isRdiMode() && (rc != NO_ERROR)) {
8680             if (recordingHint) {
8681                 delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
8682                 delChannel(QCAMERA_CH_TYPE_VIDEO);
8683             }
8684         }
8685 
8686         if (mParameters.isUBWCEnabled() && !recordingHint) {
8687             cam_format_t fmt;
8688             mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW, fmt);
8689             if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
8690                 rc = addChannel(QCAMERA_CH_TYPE_CALLBACK);
8691                 if (rc != NO_ERROR) {
8692                     delChannel(QCAMERA_CH_TYPE_PREVIEW);
8693                     if (!isRdiMode()) {
8694                         delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
8695                         delChannel(QCAMERA_CH_TYPE_VIDEO);
8696                     }
8697                     LOGE("failed!! rc = %d", rc);
8698                     return rc;
8699                 }
8700             }
8701         }
8702 
8703         if (NO_ERROR != rc) {
8704             delChannel(QCAMERA_CH_TYPE_PREVIEW);
8705             LOGE("failed!! rc = %d", rc);
8706         }
8707     }
8708 
8709     LOGI("X rc = %d", rc);
8710     return rc;
8711 }
8712 
8713 /*===========================================================================
8714  * FUNCTION   : unpreparePreview
8715  *
8716  * DESCRIPTION: delete channels for preview
8717  *
8718  * PARAMETERS : none
8719  *
8720  * RETURN     : none
8721  *==========================================================================*/
unpreparePreview()8722 void QCamera2HardwareInterface::unpreparePreview()
8723 {
8724     delChannel(QCAMERA_CH_TYPE_ZSL);
8725     delChannel(QCAMERA_CH_TYPE_PREVIEW);
8726     delChannel(QCAMERA_CH_TYPE_VIDEO);
8727     delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
8728     delChannel(QCAMERA_CH_TYPE_CALLBACK);
8729     delChannel(QCAMERA_CH_TYPE_RAW);
8730 }
8731 
8732 /*===========================================================================
8733  * FUNCTION   : playShutter
8734  *
8735  * DESCRIPTION: send request to play shutter sound
8736  *
8737  * PARAMETERS : none
8738  *
8739  * RETURN     : none
8740  *==========================================================================*/
playShutter()8741 void QCamera2HardwareInterface::playShutter(){
8742      if (mNotifyCb == NULL ||
8743          msgTypeEnabledWithLock(CAMERA_MSG_SHUTTER) == 0){
8744          LOGD("shutter msg not enabled or NULL cb");
8745          return;
8746      }
8747      LOGH("CAMERA_MSG_SHUTTER ");
8748      qcamera_callback_argm_t cbArg;
8749      memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
8750      cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK;
8751      cbArg.msg_type = CAMERA_MSG_SHUTTER;
8752      cbArg.ext1 = 0;
8753      cbArg.ext2 = false;
8754      m_cbNotifier.notifyCallback(cbArg);
8755 }
8756 
8757 /*===========================================================================
8758  * FUNCTION   : getChannelByHandle
8759  *
8760  * DESCRIPTION: return a channel by its handle
8761  *
8762  * PARAMETERS :
8763  *   @channelHandle : channel handle
8764  *
8765  * RETURN     : a channel obj if found, NULL if not found
8766  *==========================================================================*/
getChannelByHandle(uint32_t channelHandle)8767 QCameraChannel *QCamera2HardwareInterface::getChannelByHandle(uint32_t channelHandle)
8768 {
8769     for(int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
8770         if (m_channels[i] != NULL &&
8771             (validate_handle(m_channels[i]->getMyHandle(), channelHandle))) {
8772             return m_channels[i];
8773         }
8774     }
8775 
8776     return NULL;
8777 }
8778 /*===========================================================================
8779  * FUNCTION   : needPreviewFDCallback
8780  *
8781  * DESCRIPTION: decides if needPreviewFDCallback
8782  *
8783  * PARAMETERS :
8784  *   @num_faces : number of faces
8785  *
8786  * RETURN     : bool type of status
8787  *              true  -- success
8788  *              fale -- failure code
8789  *==========================================================================*/
needPreviewFDCallback(uint8_t num_faces)8790 bool QCamera2HardwareInterface::needPreviewFDCallback(uint8_t num_faces)
8791 {
8792     if (num_faces == 0 && mNumPreviewFaces == 0) {
8793         return false;
8794     }
8795 
8796     return true;
8797 }
8798 
8799 /*===========================================================================
8800  * FUNCTION   : processFaceDetectionReuslt
8801  *
8802  * DESCRIPTION: process face detection reuslt
8803  *
8804  * PARAMETERS :
8805  *   @faces_data : ptr to face processing result struct
8806  *
8807  * RETURN     : int32_t type of status
8808  *              NO_ERROR  -- success
8809  *              none-zero failure code
8810  *==========================================================================*/
processFaceDetectionResult(cam_faces_data_t * faces_data)8811 int32_t QCamera2HardwareInterface::processFaceDetectionResult(cam_faces_data_t *faces_data)
8812 {
8813     if (!mParameters.isFaceDetectionEnabled()) {
8814         LOGH("FaceDetection not enabled, no ops here");
8815         return NO_ERROR;
8816     }
8817 
8818     qcamera_face_detect_type_t fd_type = faces_data->detection_data.fd_type;
8819     cam_face_detection_data_t *detect_data = &(faces_data->detection_data);
8820     if ((NULL == mDataCb) ||
8821         (fd_type == QCAMERA_FD_PREVIEW && !msgTypeEnabled(CAMERA_MSG_PREVIEW_METADATA)) ||
8822         (!needPreviewFDCallback(detect_data->num_faces_detected))
8823 #ifndef VANILLA_HAL
8824         || (fd_type == QCAMERA_FD_SNAPSHOT && !msgTypeEnabled(CAMERA_MSG_META_DATA))
8825 #endif
8826         ) {
8827         LOGH("metadata msgtype not enabled, no ops here");
8828         return NO_ERROR;
8829     }
8830 
8831     if ((fd_type == QCAMERA_FD_PREVIEW) && (detect_data->update_flag == FALSE)) {
8832         // Don't send callback to app if this is skipped by fd at backend
8833         return NO_ERROR;
8834     }
8835 
8836     cam_dimension_t display_dim;
8837     mParameters.getStreamDimension(CAM_STREAM_TYPE_PREVIEW, display_dim);
8838     if (display_dim.width <= 0 || display_dim.height <= 0) {
8839         LOGE("Invalid preview width or height (%d x %d)",
8840                display_dim.width, display_dim.height);
8841         return UNKNOWN_ERROR;
8842     }
8843 
8844     // process face detection result
8845     // need separate face detection in preview or snapshot type
8846     size_t faceResultSize = 0;
8847     size_t data_len = 0;
8848     if(fd_type == QCAMERA_FD_PREVIEW){
8849         //fd for preview frames
8850         faceResultSize = sizeof(camera_frame_metadata_t);
8851         faceResultSize += sizeof(camera_face_t) * MAX_ROI;
8852     }else if(fd_type == QCAMERA_FD_SNAPSHOT){
8853 #ifndef VANILLA_HAL
8854         // fd for snapshot frames
8855         //check if face is detected in this frame
8856         if(detect_data->num_faces_detected > 0){
8857             data_len = sizeof(camera_frame_metadata_t) +
8858                     sizeof(camera_face_t) * detect_data->num_faces_detected;
8859         }else{
8860             //no face
8861             data_len = 0;
8862         }
8863 #endif
8864         faceResultSize = 1 *sizeof(int)    //meta data type
8865                        + 1 *sizeof(int)    // meta data len
8866                        + data_len;         //data
8867     }
8868 
8869     camera_memory_t *faceResultBuffer = mGetMemory(-1,
8870                                                    faceResultSize,
8871                                                    1,
8872                                                    mCallbackCookie);
8873     if ( NULL == faceResultBuffer ) {
8874         LOGE("Not enough memory for face result data");
8875         return NO_MEMORY;
8876     }
8877 
8878     unsigned char *pFaceResult = ( unsigned char * ) faceResultBuffer->data;
8879     memset(pFaceResult, 0, faceResultSize);
8880     unsigned char *faceData = NULL;
8881     if(fd_type == QCAMERA_FD_PREVIEW){
8882         faceData = pFaceResult;
8883         mNumPreviewFaces = detect_data->num_faces_detected;
8884     }else if(fd_type == QCAMERA_FD_SNAPSHOT){
8885 #ifndef VANILLA_HAL
8886         //need fill meta type and meta data len first
8887         int *data_header = (int* )pFaceResult;
8888         data_header[0] = CAMERA_META_DATA_FD;
8889         data_header[1] = (int)data_len;
8890 
8891         if(data_len <= 0){
8892             //if face is not valid or do not have face, return
8893             qcamera_callback_argm_t cbArg;
8894             memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
8895             cbArg.cb_type = QCAMERA_DATA_CALLBACK;
8896             cbArg.msg_type = CAMERA_MSG_META_DATA;
8897             cbArg.data = faceResultBuffer;
8898             cbArg.user_data = faceResultBuffer;
8899             cbArg.cookie = this;
8900             cbArg.release_cb = releaseCameraMemory;
8901             int32_t rc = m_cbNotifier.notifyCallback(cbArg);
8902             if (rc != NO_ERROR) {
8903                 LOGE("fail sending notification");
8904                 faceResultBuffer->release(faceResultBuffer);
8905             }
8906             return rc;
8907         }
8908 #endif
8909         faceData = pFaceResult + 2 *sizeof(int); //skip two int length
8910     }
8911 
8912     camera_frame_metadata_t *roiData = (camera_frame_metadata_t * ) faceData;
8913     camera_face_t *faces = (camera_face_t *) ( faceData + sizeof(camera_frame_metadata_t) );
8914 
8915     roiData->number_of_faces = detect_data->num_faces_detected;
8916     roiData->faces = faces;
8917     if (roiData->number_of_faces > 0) {
8918         for (int i = 0; i < roiData->number_of_faces; i++) {
8919             faces[i].id = detect_data->faces[i].face_id;
8920             faces[i].score = detect_data->faces[i].score;
8921 
8922             // left
8923             faces[i].rect[0] = MAP_TO_DRIVER_COORDINATE(
8924                     detect_data->faces[i].face_boundary.left,
8925                     display_dim.width, 2000, -1000);
8926 
8927             // top
8928             faces[i].rect[1] = MAP_TO_DRIVER_COORDINATE(
8929                     detect_data->faces[i].face_boundary.top,
8930                     display_dim.height, 2000, -1000);
8931 
8932             // right
8933             faces[i].rect[2] = faces[i].rect[0] +
8934                     MAP_TO_DRIVER_COORDINATE(
8935                     detect_data->faces[i].face_boundary.width,
8936                     display_dim.width, 2000, 0);
8937 
8938              // bottom
8939             faces[i].rect[3] = faces[i].rect[1] +
8940                     MAP_TO_DRIVER_COORDINATE(
8941                     detect_data->faces[i].face_boundary.height,
8942                     display_dim.height, 2000, 0);
8943 
8944             if (faces_data->landmark_valid) {
8945                 // Center of left eye
8946                 if (faces_data->landmark_data.face_landmarks[i].is_left_eye_valid) {
8947                     faces[i].left_eye[0] = MAP_TO_DRIVER_COORDINATE(
8948                             faces_data->landmark_data.face_landmarks[i].left_eye_center.x,
8949                             display_dim.width, 2000, -1000);
8950                     faces[i].left_eye[1] = MAP_TO_DRIVER_COORDINATE(
8951                             faces_data->landmark_data.face_landmarks[i].left_eye_center.y,
8952                             display_dim.height, 2000, -1000);
8953                 } else {
8954                     faces[i].left_eye[0] = FACE_INVALID_POINT;
8955                     faces[i].left_eye[1] = FACE_INVALID_POINT;
8956                 }
8957 
8958                 // Center of right eye
8959                 if (faces_data->landmark_data.face_landmarks[i].is_right_eye_valid) {
8960                     faces[i].right_eye[0] = MAP_TO_DRIVER_COORDINATE(
8961                             faces_data->landmark_data.face_landmarks[i].right_eye_center.x,
8962                             display_dim.width, 2000, -1000);
8963                     faces[i].right_eye[1] = MAP_TO_DRIVER_COORDINATE(
8964                             faces_data->landmark_data.face_landmarks[i].right_eye_center.y,
8965                             display_dim.height, 2000, -1000);
8966                 } else {
8967                     faces[i].right_eye[0] = FACE_INVALID_POINT;
8968                     faces[i].right_eye[1] = FACE_INVALID_POINT;
8969                 }
8970 
8971                 // Center of mouth
8972                 if (faces_data->landmark_data.face_landmarks[i].is_mouth_valid) {
8973                     faces[i].mouth[0] = MAP_TO_DRIVER_COORDINATE(
8974                             faces_data->landmark_data.face_landmarks[i].mouth_center.x,
8975                             display_dim.width, 2000, -1000);
8976                     faces[i].mouth[1] = MAP_TO_DRIVER_COORDINATE(
8977                             faces_data->landmark_data.face_landmarks[i].mouth_center.y,
8978                             display_dim.height, 2000, -1000);
8979                 } else {
8980                     faces[i].mouth[0] = FACE_INVALID_POINT;
8981                     faces[i].mouth[1] = FACE_INVALID_POINT;
8982                 }
8983             } else {
8984                 // return -2000 if invalid
8985                 faces[i].left_eye[0] = FACE_INVALID_POINT;
8986                 faces[i].left_eye[1] = FACE_INVALID_POINT;
8987 
8988                 faces[i].right_eye[0] = FACE_INVALID_POINT;
8989                 faces[i].right_eye[1] = FACE_INVALID_POINT;
8990 
8991                 faces[i].mouth[0] = FACE_INVALID_POINT;
8992                 faces[i].mouth[1] = FACE_INVALID_POINT;
8993             }
8994 
8995 #ifndef VANILLA_HAL
8996 #ifdef TARGET_TS_MAKEUP
8997             mFaceRect.left = detect_data->faces[i].face_boundary.left;
8998             mFaceRect.top = detect_data->faces[i].face_boundary.top;
8999             mFaceRect.right = detect_data->faces[i].face_boundary.width+mFaceRect.left;
9000             mFaceRect.bottom = detect_data->faces[i].face_boundary.height+mFaceRect.top;
9001 #endif
9002             if (faces_data->smile_valid) {
9003                 faces[i].smile_degree = faces_data->smile_data.smile[i].smile_degree;
9004                 faces[i].smile_score = faces_data->smile_data.smile[i].smile_confidence;
9005             }
9006             if (faces_data->blink_valid) {
9007                 faces[i].blink_detected = faces_data->blink_data.blink[i].blink_detected;
9008                 faces[i].leye_blink = faces_data->blink_data.blink[i].left_blink;
9009                 faces[i].reye_blink = faces_data->blink_data.blink[i].right_blink;
9010             }
9011             if (faces_data->recog_valid) {
9012                 faces[i].face_recognised = faces_data->recog_data.face_rec[i].face_recognised;
9013             }
9014             if (faces_data->gaze_valid) {
9015                 faces[i].gaze_angle = faces_data->gaze_data.gaze[i].gaze_angle;
9016                 faces[i].updown_dir = faces_data->gaze_data.gaze[i].updown_dir;
9017                 faces[i].leftright_dir = faces_data->gaze_data.gaze[i].leftright_dir;
9018                 faces[i].roll_dir = faces_data->gaze_data.gaze[i].roll_dir;
9019                 faces[i].left_right_gaze = faces_data->gaze_data.gaze[i].left_right_gaze;
9020                 faces[i].top_bottom_gaze = faces_data->gaze_data.gaze[i].top_bottom_gaze;
9021             }
9022 #endif
9023 
9024         }
9025     }
9026     else{
9027 #ifdef TARGET_TS_MAKEUP
9028         memset(&mFaceRect,-1,sizeof(mFaceRect));
9029 #endif
9030     }
9031     qcamera_callback_argm_t cbArg;
9032     memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
9033     cbArg.cb_type = QCAMERA_DATA_CALLBACK;
9034     if(fd_type == QCAMERA_FD_PREVIEW){
9035         cbArg.msg_type = CAMERA_MSG_PREVIEW_METADATA;
9036     }
9037 #ifndef VANILLA_HAL
9038     else if(fd_type == QCAMERA_FD_SNAPSHOT){
9039         cbArg.msg_type = CAMERA_MSG_META_DATA;
9040     }
9041 #endif
9042     cbArg.data = faceResultBuffer;
9043     cbArg.metadata = roiData;
9044     cbArg.user_data = faceResultBuffer;
9045     cbArg.cookie = this;
9046     cbArg.release_cb = releaseCameraMemory;
9047     int32_t rc = m_cbNotifier.notifyCallback(cbArg);
9048     if (rc != NO_ERROR) {
9049         LOGE("fail sending notification");
9050         faceResultBuffer->release(faceResultBuffer);
9051     }
9052 
9053     return rc;
9054 }
9055 
9056 /*===========================================================================
9057  * FUNCTION   : releaseCameraMemory
9058  *
9059  * DESCRIPTION: releases camera memory objects
9060  *
9061  * PARAMETERS :
9062  *   @data    : buffer to be released
9063  *   @cookie  : context data
9064  *   @cbStatus: callback status
9065  *
9066  * RETURN     : None
9067  *==========================================================================*/
releaseCameraMemory(void * data,void *,int32_t)9068 void QCamera2HardwareInterface::releaseCameraMemory(void *data,
9069                                                     void */*cookie*/,
9070                                                     int32_t /*cbStatus*/)
9071 {
9072     camera_memory_t *mem = ( camera_memory_t * ) data;
9073     if ( NULL != mem ) {
9074         mem->release(mem);
9075     }
9076 }
9077 
9078 /*===========================================================================
9079  * FUNCTION   : returnStreamBuffer
9080  *
9081  * DESCRIPTION: returns back a stream buffer
9082  *
9083  * PARAMETERS :
9084  *   @data    : buffer to be released
9085  *   @cookie  : context data
9086  *   @cbStatus: callback status
9087  *
9088  * RETURN     : None
9089  *==========================================================================*/
returnStreamBuffer(void * data,void * cookie,int32_t)9090 void QCamera2HardwareInterface::returnStreamBuffer(void *data,
9091                                                    void *cookie,
9092                                                    int32_t /*cbStatus*/)
9093 {
9094     QCameraStream *stream = ( QCameraStream * ) cookie;
9095     int idx = *((int *)data);
9096     if ((NULL != stream) && (0 <= idx)) {
9097         stream->bufDone((uint32_t)idx);
9098     } else {
9099         LOGE("Cannot return buffer %d %p", idx, cookie);
9100     }
9101 }
9102 
9103 /*===========================================================================
9104  * FUNCTION   : processHistogramStats
9105  *
9106  * DESCRIPTION: process histogram stats
9107  *
9108  * PARAMETERS :
9109  *   @hist_data : ptr to histogram stats struct
9110  *
9111  * RETURN     : int32_t type of status
9112  *              NO_ERROR  -- success
9113  *              none-zero failure code
9114  *==========================================================================*/
processHistogramStats(__unused cam_hist_stats_t & stats_data)9115 int32_t QCamera2HardwareInterface::processHistogramStats(
9116         __unused cam_hist_stats_t &stats_data)
9117 {
9118 #ifndef VANILLA_HAL
9119     if (!mParameters.isHistogramEnabled()) {
9120         LOGH("Histogram not enabled, no ops here");
9121         return NO_ERROR;
9122     }
9123 
9124     camera_memory_t *histBuffer = mGetMemory(-1,
9125                                              sizeof(cam_histogram_data_t),
9126                                              1,
9127                                              mCallbackCookie);
9128     if ( NULL == histBuffer ) {
9129         LOGE("Not enough memory for histogram data");
9130         return NO_MEMORY;
9131     }
9132 
9133     cam_histogram_data_t *pHistData = (cam_histogram_data_t *)histBuffer->data;
9134     if (pHistData == NULL) {
9135         LOGE("memory data ptr is NULL");
9136         return UNKNOWN_ERROR;
9137     }
9138 
9139     switch (stats_data.type) {
9140     case CAM_HISTOGRAM_TYPE_BAYER:
9141         switch (stats_data.bayer_stats.data_type) {
9142             case CAM_STATS_CHANNEL_Y:
9143             case CAM_STATS_CHANNEL_R:
9144                 *pHistData = stats_data.bayer_stats.r_stats;
9145                 break;
9146             case CAM_STATS_CHANNEL_GR:
9147                 *pHistData = stats_data.bayer_stats.gr_stats;
9148                 break;
9149             case CAM_STATS_CHANNEL_GB:
9150             case CAM_STATS_CHANNEL_ALL:
9151                 *pHistData = stats_data.bayer_stats.gb_stats;
9152                 break;
9153             case CAM_STATS_CHANNEL_B:
9154                 *pHistData = stats_data.bayer_stats.b_stats;
9155                 break;
9156             default:
9157                 *pHistData = stats_data.bayer_stats.r_stats;
9158                 break;
9159         }
9160         break;
9161     case CAM_HISTOGRAM_TYPE_YUV:
9162         *pHistData = stats_data.yuv_stats;
9163         break;
9164     }
9165 
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_STATS_DATA;
9170     cbArg.data = histBuffer;
9171     cbArg.user_data = histBuffer;
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         histBuffer->release(histBuffer);
9178     }
9179 #endif
9180     return NO_ERROR;
9181 }
9182 
9183 /*===========================================================================
9184  * FUNCTION   : calcThermalLevel
9185  *
9186  * DESCRIPTION: Calculates the target fps range depending on
9187  *              the thermal level.
9188  *              Note that this function can be called from QCameraParametersIntf
9189  *              while mutex is held. So it should not call back into
9190  *              QCameraParametersIntf causing deadlock.
9191  *
9192  * PARAMETERS :
9193  *   @level      : received thermal level
9194  *   @minFPS     : minimum configured fps range
9195  *   @maxFPS     : maximum configured fps range
9196  *   @minVideoFps: minimum configured fps range
9197  *   @maxVideoFps: maximum configured fps range
9198  *   @adjustedRange : target fps range
9199  *   @skipPattern : target skip pattern
9200  *   @bRecordingHint : recording hint value
9201  *
9202  * RETURN     : int32_t type of status
9203  *              NO_ERROR  -- success
9204  *              none-zero failure code
9205  *==========================================================================*/
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)9206 int QCamera2HardwareInterface::calcThermalLevel(
9207             qcamera_thermal_level_enum_t level,
9208             const int minFPSi,
9209             const int maxFPSi,
9210             const float &minVideoFps,
9211             const float &maxVideoFps,
9212             cam_fps_range_t &adjustedRange,
9213             enum msm_vfe_frame_skip_pattern &skipPattern,
9214             bool bRecordingHint)
9215 {
9216     const float minFPS = (float)minFPSi;
9217     const float maxFPS = (float)maxFPSi;
9218 
9219     LOGH("level: %d, preview minfps %f, preview maxfpS %f, "
9220               "video minfps %f, video maxfpS %f",
9221              level, minFPS, maxFPS, minVideoFps, maxVideoFps);
9222 
9223     switch(level) {
9224     case QCAMERA_THERMAL_NO_ADJUSTMENT:
9225         {
9226             adjustedRange.min_fps = minFPS / 1000.0f;
9227             adjustedRange.max_fps = maxFPS / 1000.0f;
9228             adjustedRange.video_min_fps = minVideoFps / 1000.0f;
9229             adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
9230             skipPattern = NO_SKIP;
9231         }
9232         break;
9233     case QCAMERA_THERMAL_SLIGHT_ADJUSTMENT:
9234         {
9235             adjustedRange.min_fps = minFPS / 1000.0f;
9236             adjustedRange.max_fps = maxFPS / 1000.0f;
9237             adjustedRange.min_fps -= 0.1f * adjustedRange.min_fps;
9238             adjustedRange.max_fps -= 0.1f * adjustedRange.max_fps;
9239             adjustedRange.video_min_fps = minVideoFps / 1000.0f;
9240             adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
9241             adjustedRange.video_min_fps -= 0.1f * adjustedRange.video_min_fps;
9242             adjustedRange.video_max_fps -= 0.1f * adjustedRange.video_max_fps;
9243             if ( adjustedRange.min_fps < 1 ) {
9244                 adjustedRange.min_fps = 1;
9245             }
9246             if ( adjustedRange.max_fps < 1 ) {
9247                 adjustedRange.max_fps = 1;
9248             }
9249             if ( adjustedRange.video_min_fps < 1 ) {
9250                 adjustedRange.video_min_fps = 1;
9251             }
9252             if ( adjustedRange.video_max_fps < 1 ) {
9253                 adjustedRange.video_max_fps = 1;
9254             }
9255             skipPattern = EVERY_2FRAME;
9256         }
9257         break;
9258     case QCAMERA_THERMAL_BIG_ADJUSTMENT:
9259         {
9260             adjustedRange.min_fps = minFPS / 1000.0f;
9261             adjustedRange.max_fps = maxFPS / 1000.0f;
9262             adjustedRange.min_fps -= 0.2f * adjustedRange.min_fps;
9263             adjustedRange.max_fps -= 0.2f * adjustedRange.max_fps;
9264             adjustedRange.video_min_fps = minVideoFps / 1000.0f;
9265             adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
9266             adjustedRange.video_min_fps -= 0.2f * adjustedRange.video_min_fps;
9267             adjustedRange.video_max_fps -= 0.2f * adjustedRange.video_max_fps;
9268             if ( adjustedRange.min_fps < 1 ) {
9269                 adjustedRange.min_fps = 1;
9270             }
9271             if ( adjustedRange.max_fps < 1 ) {
9272                 adjustedRange.max_fps = 1;
9273             }
9274             if ( adjustedRange.video_min_fps < 1 ) {
9275                 adjustedRange.video_min_fps = 1;
9276             }
9277             if ( adjustedRange.video_max_fps < 1 ) {
9278                 adjustedRange.video_max_fps = 1;
9279             }
9280             skipPattern = EVERY_4FRAME;
9281         }
9282         break;
9283     case QCAMERA_THERMAL_MAX_ADJUSTMENT:
9284         {
9285             // Stop Preview?
9286             // Set lowest min FPS for now
9287             adjustedRange.min_fps = minFPS/1000.0f;
9288             adjustedRange.max_fps = minFPS/1000.0f;
9289             cam_capability_t *capability = gCamCapability[mCameraId];
9290             for (size_t i = 0;
9291                      i < capability->fps_ranges_tbl_cnt;
9292                      i++) {
9293                 if (capability->fps_ranges_tbl[i].min_fps <
9294                         adjustedRange.min_fps) {
9295                     adjustedRange.min_fps =
9296                             capability->fps_ranges_tbl[i].min_fps;
9297                     adjustedRange.max_fps = adjustedRange.min_fps;
9298                 }
9299             }
9300             skipPattern = MAX_SKIP;
9301             adjustedRange.video_min_fps = adjustedRange.min_fps;
9302             adjustedRange.video_max_fps = adjustedRange.max_fps;
9303         }
9304         break;
9305     case QCAMERA_THERMAL_SHUTDOWN:
9306         {
9307             // send error notify
9308             LOGE("Received shutdown thermal level. Closing camera");
9309             sendEvtNotify(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0);
9310         }
9311         break;
9312     default:
9313         {
9314             LOGW("Invalid thermal level %d", level);
9315             return BAD_VALUE;
9316         }
9317         break;
9318     }
9319     if (level >= QCAMERA_THERMAL_NO_ADJUSTMENT && level <= QCAMERA_THERMAL_MAX_ADJUSTMENT) {
9320         if (bRecordingHint) {
9321             adjustedRange.min_fps = minFPS / 1000.0f;
9322             adjustedRange.max_fps = maxFPS / 1000.0f;
9323             adjustedRange.video_min_fps = minVideoFps / 1000.0f;
9324             adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
9325             skipPattern = NO_SKIP;
9326             LOGH("No FPS mitigation in camcorder mode");
9327         }
9328         LOGH("Thermal level %d, FPS [%3.2f,%3.2f, %3.2f,%3.2f], frameskip %d",
9329                   level, adjustedRange.min_fps, adjustedRange.max_fps,
9330                     adjustedRange.video_min_fps, adjustedRange.video_max_fps, skipPattern);
9331     }
9332 
9333     return NO_ERROR;
9334 }
9335 
9336 /*===========================================================================
9337  * FUNCTION   : recalcFPSRange
9338  *
9339  * DESCRIPTION: adjust the configured fps range regarding
9340  *              the last thermal level.
9341  *
9342  * PARAMETERS :
9343  *   @minFPS      : minimum configured fps range
9344  *   @maxFPS      : maximum configured fps range
9345  *   @minVideoFPS : minimum configured video fps
9346  *   @maxVideoFPS : maximum configured video fps
9347  *   @adjustedRange : target fps range
9348  *   @bRecordingHint : recording hint value
9349  *
9350  * RETURN     : int32_t type of status
9351  *              NO_ERROR  -- success
9352  *              none-zero failure code
9353  *==========================================================================*/
recalcFPSRange(int & minFPS,int & maxFPS,const float & minVideoFPS,const float & maxVideoFPS,cam_fps_range_t & adjustedRange,bool bRecordingHint)9354 int QCamera2HardwareInterface::recalcFPSRange(int &minFPS, int &maxFPS,
9355         const float &minVideoFPS, const float &maxVideoFPS,
9356         cam_fps_range_t &adjustedRange, bool bRecordingHint)
9357 {
9358     enum msm_vfe_frame_skip_pattern skipPattern;
9359     calcThermalLevel(mThermalLevel,
9360                      minFPS,
9361                      maxFPS,
9362                      minVideoFPS,
9363                      maxVideoFPS,
9364                      adjustedRange,
9365                      skipPattern,
9366                      bRecordingHint);
9367     return NO_ERROR;
9368 }
9369 
9370 /*===========================================================================
9371  * FUNCTION   : updateThermalLevel
9372  *
9373  * DESCRIPTION: update thermal level depending on thermal events
9374  *
9375  * PARAMETERS :
9376  *   @level   : thermal level
9377  *
9378  * RETURN     : int32_t type of status
9379  *              NO_ERROR  -- success
9380  *              none-zero failure code
9381  *==========================================================================*/
updateThermalLevel(void * thermal_level)9382 int QCamera2HardwareInterface::updateThermalLevel(void *thermal_level)
9383 {
9384     int ret = NO_ERROR;
9385     cam_fps_range_t adjustedRange;
9386     int minFPS, maxFPS;
9387     float minVideoFPS, maxVideoFPS;
9388     enum msm_vfe_frame_skip_pattern skipPattern;
9389     bool value;
9390     qcamera_thermal_level_enum_t level = *(qcamera_thermal_level_enum_t *)thermal_level;
9391 
9392 
9393     if (!mCameraOpened) {
9394         LOGH("Camera is not opened, no need to update camera parameters");
9395         return NO_ERROR;
9396     }
9397 
9398     mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
9399     qcamera_thermal_mode thermalMode = mParameters.getThermalMode();
9400     if (mParameters.isHfrMode()) {
9401         cam_fps_range_t hfrFpsRange;
9402         mParameters.getHfrFps(hfrFpsRange);
9403         minVideoFPS = hfrFpsRange.video_min_fps;
9404         maxVideoFPS = hfrFpsRange.video_max_fps;
9405     } else {
9406         minVideoFPS = minFPS;
9407         maxVideoFPS = maxFPS;
9408     }
9409 
9410     value = mParameters.getRecordingHintValue();
9411     calcThermalLevel(level, minFPS, maxFPS, minVideoFPS, maxVideoFPS,
9412             adjustedRange, skipPattern, value );
9413     mThermalLevel = level;
9414 
9415     if (thermalMode == QCAMERA_THERMAL_ADJUST_FPS)
9416         ret = mParameters.adjustPreviewFpsRange(&adjustedRange);
9417     else if (thermalMode == QCAMERA_THERMAL_ADJUST_FRAMESKIP)
9418         ret = mParameters.setFrameSkip(skipPattern);
9419     else
9420         LOGW("Incorrect thermal mode %d", thermalMode);
9421 
9422     return ret;
9423 
9424 }
9425 
9426 /*===========================================================================
9427  * FUNCTION   : updateParameters
9428  *
9429  * DESCRIPTION: update parameters
9430  *
9431  * PARAMETERS :
9432  *   @parms       : input parameters string
9433  *   @needRestart : output, flag to indicate if preview restart is needed
9434  *
9435  * RETURN     : int32_t type of status
9436  *              NO_ERROR  -- success
9437  *              none-zero failure code
9438  *==========================================================================*/
updateParameters(const char * parms,bool & needRestart)9439 int QCamera2HardwareInterface::updateParameters(const char *parms, bool &needRestart)
9440 {
9441     int rc = NO_ERROR;
9442 
9443     String8 str = String8(parms);
9444     rc =  mParameters.updateParameters(str, needRestart);
9445     setNeedRestart(needRestart);
9446 
9447     // update stream based parameter settings
9448     for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
9449         if (m_channels[i] != NULL) {
9450             m_channels[i]->UpdateStreamBasedParameters(mParameters);
9451         }
9452     }
9453 
9454     return rc;
9455 }
9456 
9457 /*===========================================================================
9458  * FUNCTION   : commitParameterChanges
9459  *
9460  * DESCRIPTION: commit parameter changes to the backend to take effect
9461  *
9462  * PARAMETERS : none
9463  *
9464  * RETURN     : int32_t type of status
9465  *              NO_ERROR  -- success
9466  *              none-zero failure code
9467  * NOTE       : This function must be called after updateParameters.
9468  *              Otherwise, no change will be passed to backend to take effect.
9469  *==========================================================================*/
commitParameterChanges()9470 int QCamera2HardwareInterface::commitParameterChanges()
9471 {
9472     int rc = NO_ERROR;
9473     rc = mParameters.commitParameters();
9474     if (rc == NO_ERROR) {
9475         // update number of snapshot based on committed parameters setting
9476         rc = mParameters.setNumOfSnapshot();
9477     }
9478     return rc;
9479 }
9480 
9481 /*===========================================================================
9482  * FUNCTION   : needDebugFps
9483  *
9484  * DESCRIPTION: if fps log info need to be printed out
9485  *
9486  * PARAMETERS : none
9487  *
9488  * RETURN     : true: need print out fps log
9489  *              false: no need to print out fps log
9490  *==========================================================================*/
needDebugFps()9491 bool QCamera2HardwareInterface::needDebugFps()
9492 {
9493     bool needFps = false;
9494     needFps = mParameters.isFpsDebugEnabled();
9495     return needFps;
9496 }
9497 
9498 /*===========================================================================
9499  * FUNCTION   : isCACEnabled
9500  *
9501  * DESCRIPTION: if CAC is enabled
9502  *
9503  * PARAMETERS : none
9504  *
9505  * RETURN     : true: needed
9506  *              false: no need
9507  *==========================================================================*/
isCACEnabled()9508 bool QCamera2HardwareInterface::isCACEnabled()
9509 {
9510     char prop[PROPERTY_VALUE_MAX];
9511     memset(prop, 0, sizeof(prop));
9512     property_get("persist.camera.feature.cac", prop, "0");
9513     int enableCAC = atoi(prop);
9514     return enableCAC == 1;
9515 }
9516 
9517 /*===========================================================================
9518  * FUNCTION   : is4k2kResolution
9519  *
9520  * DESCRIPTION: if resolution is 4k x 2k or true 4k x 2k
9521  *
9522  * PARAMETERS : none
9523  *
9524  * RETURN     : true: needed
9525  *              false: no need
9526  *==========================================================================*/
is4k2kResolution(cam_dimension_t * resolution)9527 bool QCamera2HardwareInterface::is4k2kResolution(cam_dimension_t* resolution)
9528 {
9529    bool enabled = false;
9530    if ((resolution->width == 4096 && resolution->height == 2160) ||
9531        (resolution->width == 3840 && resolution->height == 2160) ) {
9532       enabled = true;
9533    }
9534    return enabled;
9535 }
9536 
9537 /*===========================================================================
9538  * FUNCTION   : isPreviewRestartEnabled
9539  *
9540  * DESCRIPTION: Check whether preview should be restarted automatically
9541  *              during image capture.
9542  *
9543  * PARAMETERS : none
9544  *
9545  * RETURN     : true: needed
9546  *              false: no need
9547  *==========================================================================*/
isPreviewRestartEnabled()9548 bool QCamera2HardwareInterface::isPreviewRestartEnabled()
9549 {
9550     char prop[PROPERTY_VALUE_MAX];
9551     memset(prop, 0, sizeof(prop));
9552     property_get("persist.camera.feature.restart", prop, "0");
9553     int earlyRestart = atoi(prop);
9554     return earlyRestart == 1;
9555 }
9556 
9557 /*===========================================================================
9558  * FUNCTION   : needReprocess
9559  *
9560  * DESCRIPTION: if reprocess is needed
9561  *
9562  * PARAMETERS : none
9563  *
9564  * RETURN     : true: needed
9565  *              false: no need
9566  *==========================================================================*/
needReprocess()9567 bool QCamera2HardwareInterface::needReprocess()
9568 {
9569     bool needReprocess = false;
9570 
9571     if (!mParameters.isJpegPictureFormat() &&
9572         !mParameters.isNV21PictureFormat()) {
9573         // RAW image, no need to reprocess
9574         return false;
9575     }
9576 
9577     //Disable reprocess for 4K liveshot case but enable if lowpower mode
9578     if (mParameters.is4k2kVideoResolution() && mParameters.getRecordingHintValue()
9579             && !isLowPowerMode()) {
9580         return false;
9581     }
9582 
9583     // pp feature config
9584     cam_pp_feature_config_t pp_config;
9585     memset(&pp_config, 0, sizeof(cam_pp_feature_config_t));
9586 
9587     //Decide whether to do reprocess or not based on
9588     //ppconfig obtained in the first pass.
9589     getPPConfig(pp_config);
9590 
9591     if (pp_config.feature_mask > 0) {
9592         needReprocess = true;
9593     }
9594 
9595     LOGH("needReprocess %s", needReprocess ? "true" : "false");
9596     return needReprocess;
9597 }
9598 
9599 
9600 /*===========================================================================
9601  * FUNCTION   : needRotationReprocess
9602  *
9603  * DESCRIPTION: if rotation needs to be done by reprocess in pp
9604  *
9605  * PARAMETERS : none
9606  *
9607  * RETURN     : true: needed
9608  *              false: no need
9609  *==========================================================================*/
needRotationReprocess()9610 bool QCamera2HardwareInterface::needRotationReprocess()
9611 {
9612     if (!mParameters.isJpegPictureFormat() &&
9613         !mParameters.isNV21PictureFormat()) {
9614         // RAW image, no need to reprocess
9615         return false;
9616     }
9617 
9618     //Disable reprocess for 4K liveshot case
9619     if (mParameters.is4k2kVideoResolution() && mParameters.getRecordingHintValue()
9620             && !isLowPowerMode()) {
9621         //Disable reprocess for 4K liveshot case
9622         return false;
9623     }
9624 
9625     if ((gCamCapability[mCameraId]->qcom_supported_feature_mask &
9626             CAM_QCOM_FEATURE_ROTATION) > 0 &&
9627             (mParameters.getJpegRotation() > 0)) {
9628         // current rotation is not zero, and pp has the capability to process rotation
9629         LOGH("need to do reprocess for rotation=%d",
9630                  mParameters.getJpegRotation());
9631         return true;
9632     }
9633 
9634     return false;
9635 }
9636 
9637 /*===========================================================================
9638  * FUNCTION   : getThumbnailSize
9639  *
9640  * DESCRIPTION: get user set thumbnail size
9641  *
9642  * PARAMETERS :
9643  *   @dim     : output of thumbnail dimension
9644  *
9645  * RETURN     : none
9646  *==========================================================================*/
getThumbnailSize(cam_dimension_t & dim)9647 void QCamera2HardwareInterface::getThumbnailSize(cam_dimension_t &dim)
9648 {
9649     mParameters.getThumbnailSize(&dim.width, &dim.height);
9650 }
9651 
9652 /*===========================================================================
9653  * FUNCTION   : getJpegQuality
9654  *
9655  * DESCRIPTION: get user set jpeg quality
9656  *
9657  * PARAMETERS : none
9658  *
9659  * RETURN     : jpeg quality setting
9660  *==========================================================================*/
getJpegQuality()9661 uint32_t QCamera2HardwareInterface::getJpegQuality()
9662 {
9663     uint32_t quality = 0;
9664     quality =  mParameters.getJpegQuality();
9665     return quality;
9666 }
9667 
9668 /*===========================================================================
9669  * FUNCTION   : getExifData
9670  *
9671  * DESCRIPTION: get exif data to be passed into jpeg encoding
9672  *
9673  * PARAMETERS : none
9674  *
9675  * RETURN     : exif data from user setting and GPS
9676  *==========================================================================*/
getExifData()9677 QCameraExif *QCamera2HardwareInterface::getExifData()
9678 {
9679     QCameraExif *exif = new QCameraExif();
9680     if (exif == NULL) {
9681         LOGE("No memory for QCameraExif");
9682         return NULL;
9683     }
9684 
9685     int32_t rc = NO_ERROR;
9686 
9687     // add exif entries
9688     String8 dateTime, subSecTime;
9689     rc = mParameters.getExifDateTime(dateTime, subSecTime);
9690     if(rc == NO_ERROR) {
9691         exif->addEntry(EXIFTAGID_DATE_TIME, EXIF_ASCII,
9692                 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string());
9693         exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, EXIF_ASCII,
9694                 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string());
9695         exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_DIGITIZED, EXIF_ASCII,
9696                 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string());
9697         exif->addEntry(EXIFTAGID_SUBSEC_TIME, EXIF_ASCII,
9698                 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string());
9699         exif->addEntry(EXIFTAGID_SUBSEC_TIME_ORIGINAL, EXIF_ASCII,
9700                 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string());
9701         exif->addEntry(EXIFTAGID_SUBSEC_TIME_DIGITIZED, EXIF_ASCII,
9702                 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string());
9703     } else {
9704         LOGW("getExifDateTime failed");
9705     }
9706 
9707     rat_t focalLength;
9708     rc = mParameters.getExifFocalLength(&focalLength);
9709     if (rc == NO_ERROR) {
9710         exif->addEntry(EXIFTAGID_FOCAL_LENGTH,
9711                        EXIF_RATIONAL,
9712                        1,
9713                        (void *)&(focalLength));
9714     } else {
9715         LOGW("getExifFocalLength failed");
9716     }
9717 
9718     uint16_t isoSpeed = mParameters.getExifIsoSpeed();
9719     if (getSensorType() != CAM_SENSOR_YUV) {
9720         exif->addEntry(EXIFTAGID_ISO_SPEED_RATING,
9721                        EXIF_SHORT,
9722                        1,
9723                        (void *)&(isoSpeed));
9724     }
9725 
9726     char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE];
9727     uint32_t count = 0;
9728 
9729     /*gps data might not be available */
9730     rc = mParameters.getExifGpsProcessingMethod(gpsProcessingMethod, count);
9731     if(rc == NO_ERROR) {
9732         exif->addEntry(EXIFTAGID_GPS_PROCESSINGMETHOD,
9733                        EXIF_ASCII,
9734                        count,
9735                        (void *)gpsProcessingMethod);
9736     } else {
9737         LOGW("getExifGpsProcessingMethod failed");
9738     }
9739 
9740     rat_t latitude[3];
9741     char latRef[2];
9742     rc = mParameters.getExifLatitude(latitude, latRef);
9743     if(rc == NO_ERROR) {
9744         exif->addEntry(EXIFTAGID_GPS_LATITUDE,
9745                        EXIF_RATIONAL,
9746                        3,
9747                        (void *)latitude);
9748         exif->addEntry(EXIFTAGID_GPS_LATITUDE_REF,
9749                        EXIF_ASCII,
9750                        2,
9751                        (void *)latRef);
9752     } else {
9753         LOGW("getExifLatitude failed");
9754     }
9755 
9756     rat_t longitude[3];
9757     char lonRef[2];
9758     rc = mParameters.getExifLongitude(longitude, lonRef);
9759     if(rc == NO_ERROR) {
9760         exif->addEntry(EXIFTAGID_GPS_LONGITUDE,
9761                        EXIF_RATIONAL,
9762                        3,
9763                        (void *)longitude);
9764 
9765         exif->addEntry(EXIFTAGID_GPS_LONGITUDE_REF,
9766                        EXIF_ASCII,
9767                        2,
9768                        (void *)lonRef);
9769     } else {
9770         LOGW("getExifLongitude failed");
9771     }
9772 
9773     rat_t altitude;
9774     char altRef;
9775     rc = mParameters.getExifAltitude(&altitude, &altRef);
9776     if(rc == NO_ERROR) {
9777         exif->addEntry(EXIFTAGID_GPS_ALTITUDE,
9778                        EXIF_RATIONAL,
9779                        1,
9780                        (void *)&(altitude));
9781 
9782         exif->addEntry(EXIFTAGID_GPS_ALTITUDE_REF,
9783                        EXIF_BYTE,
9784                        1,
9785                        (void *)&altRef);
9786     } else {
9787         LOGW("getExifAltitude failed");
9788     }
9789 
9790     char gpsDateStamp[20];
9791     rat_t gpsTimeStamp[3];
9792     rc = mParameters.getExifGpsDateTimeStamp(gpsDateStamp, 20, gpsTimeStamp);
9793     if(rc == NO_ERROR) {
9794         exif->addEntry(EXIFTAGID_GPS_DATESTAMP,
9795                        EXIF_ASCII,
9796                        (uint32_t)(strlen(gpsDateStamp) + 1),
9797                        (void *)gpsDateStamp);
9798 
9799         exif->addEntry(EXIFTAGID_GPS_TIMESTAMP,
9800                        EXIF_RATIONAL,
9801                        3,
9802                        (void *)gpsTimeStamp);
9803     } else {
9804         LOGW("getExifGpsDataTimeStamp failed");
9805     }
9806 
9807 #ifdef ENABLE_MODEL_INFO_EXIF
9808 
9809     char value[PROPERTY_VALUE_MAX];
9810     if (property_get("persist.sys.exif.make", value, "") > 0 ||
9811             property_get("ro.product.manufacturer", value, "QCOM-AA") > 0) {
9812         exif->addEntry(EXIFTAGID_MAKE,
9813                 EXIF_ASCII, strlen(value) + 1, (void *)value);
9814     } else {
9815         LOGW("getExifMaker failed");
9816     }
9817 
9818     if (property_get("persist.sys.exif.model", value, "") > 0 ||
9819             property_get("ro.product.model", value, "QCAM-AA") > 0) {
9820         exif->addEntry(EXIFTAGID_MODEL,
9821                 EXIF_ASCII, strlen(value) + 1, (void *)value);
9822     } else {
9823         LOGW("getExifModel failed");
9824     }
9825 
9826     if (property_get("ro.build.description", value, "QCAM-AA") > 0) {
9827         exif->addEntry(EXIFTAGID_SOFTWARE, EXIF_ASCII,
9828                 (uint32_t)(strlen(value) + 1), (void *)value);
9829     } else {
9830         LOGW("getExifSoftware failed");
9831     }
9832 
9833 #endif
9834 
9835     if (mParameters.useJpegExifRotation()) {
9836         int16_t orientation;
9837         switch (mParameters.getJpegExifRotation()) {
9838         case 0:
9839             orientation = 1;
9840             break;
9841         case 90:
9842             orientation = 6;
9843             break;
9844         case 180:
9845             orientation = 3;
9846             break;
9847         case 270:
9848             orientation = 8;
9849             break;
9850         default:
9851             orientation = 1;
9852             break;
9853         }
9854         exif->addEntry(EXIFTAGID_ORIENTATION,
9855                 EXIF_SHORT,
9856                 1,
9857                 (void *)&orientation);
9858         exif->addEntry(EXIFTAGID_TN_ORIENTATION,
9859                 EXIF_SHORT,
9860                 1,
9861                 (void *)&orientation);
9862     }
9863 
9864     return exif;
9865 }
9866 
9867 /*===========================================================================
9868  * FUNCTION   : setHistogram
9869  *
9870  * DESCRIPTION: set if histogram should be enabled
9871  *
9872  * PARAMETERS :
9873  *   @histogram_en : bool flag if histogram should be enabled
9874  *
9875  * RETURN     : int32_t type of status
9876  *              NO_ERROR  -- success
9877  *              none-zero failure code
9878  *==========================================================================*/
setHistogram(bool histogram_en)9879 int32_t QCamera2HardwareInterface::setHistogram(bool histogram_en)
9880 {
9881     return mParameters.setHistogram(histogram_en);
9882 }
9883 
9884 /*===========================================================================
9885  * FUNCTION   : setFaceDetection
9886  *
9887  * DESCRIPTION: set if face detection should be enabled
9888  *
9889  * PARAMETERS :
9890  *   @enabled : bool flag if face detection should be enabled
9891  *
9892  * RETURN     : int32_t type of status
9893  *              NO_ERROR  -- success
9894  *              none-zero failure code
9895  *==========================================================================*/
setFaceDetection(bool enabled)9896 int32_t QCamera2HardwareInterface::setFaceDetection(bool enabled)
9897 {
9898     return mParameters.setFaceDetection(enabled, true);
9899 }
9900 
9901 /*===========================================================================
9902  * FUNCTION   : isCaptureShutterEnabled
9903  *
9904  * DESCRIPTION: Check whether shutter should be triggered immediately after
9905  *              capture
9906  *
9907  * PARAMETERS :
9908  *
9909  * RETURN     : true - regular capture
9910  *              false - other type of capture
9911  *==========================================================================*/
isCaptureShutterEnabled()9912 bool QCamera2HardwareInterface::isCaptureShutterEnabled()
9913 {
9914     char prop[PROPERTY_VALUE_MAX];
9915     memset(prop, 0, sizeof(prop));
9916     property_get("persist.camera.feature.shutter", prop, "0");
9917     int enableShutter = atoi(prop);
9918     return enableShutter == 1;
9919 }
9920 
9921 /*===========================================================================
9922  * FUNCTION   : needProcessPreviewFrame
9923  *
9924  * DESCRIPTION: returns whether preview frame need to be displayed
9925  *
9926  * PARAMETERS :
9927  *   @frameID : frameID of frame to be processed
9928  *
9929  * RETURN     : int32_t type of status
9930  *              NO_ERROR  -- success
9931  *              none-zero failure code
9932  *==========================================================================*/
needProcessPreviewFrame(uint32_t frameID)9933 bool QCamera2HardwareInterface::needProcessPreviewFrame(uint32_t frameID)
9934 {
9935     return (((m_stateMachine.isPreviewRunning()) &&
9936             (!isDisplayFrameToSkip(frameID)) &&
9937             (!mParameters.isInstantAECEnabled())) ||
9938             (isPreviewRestartEnabled()));
9939 }
9940 
9941 /*===========================================================================
9942  * FUNCTION   : needSendPreviewCallback
9943  *
9944  * DESCRIPTION: returns whether preview frame need to callback to APP
9945  *
9946  * PARAMETERS :
9947  *
9948  * RETURN     : true - need preview frame callbck
9949  *              false - not send preview frame callback
9950  *==========================================================================*/
needSendPreviewCallback()9951 bool QCamera2HardwareInterface::needSendPreviewCallback()
9952 {
9953     return m_stateMachine.isPreviewRunning()
9954             && (mDataCb != NULL)
9955             && (msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_FRAME) > 0)
9956             && m_stateMachine.isPreviewCallbackNeeded();
9957 };
9958 
9959 /*===========================================================================
9960  * FUNCTION   : setDisplaySkip
9961  *
9962  * DESCRIPTION: set range of frames to skip for preview
9963  *
9964  * PARAMETERS :
9965  *   @enabled : TRUE to start skipping frame to display
9966                 FALSE to stop skipping frame to display
9967  *   @skipCnt : Number of frame to skip. 0 by default
9968  *
9969  * RETURN     : None
9970  *==========================================================================*/
setDisplaySkip(bool enabled,uint8_t skipCnt)9971 void QCamera2HardwareInterface::setDisplaySkip(bool enabled, uint8_t skipCnt)
9972 {
9973     pthread_mutex_lock(&mGrallocLock);
9974     if (enabled) {
9975         setDisplayFrameSkip();
9976         setDisplayFrameSkip(mLastPreviewFrameID + skipCnt + 1);
9977     } else {
9978         setDisplayFrameSkip(mFrameSkipStart, (mLastPreviewFrameID + skipCnt + 1));
9979     }
9980     pthread_mutex_unlock(&mGrallocLock);
9981 }
9982 
9983 /*===========================================================================
9984  * FUNCTION   : setDisplayFrameSkip
9985  *
9986  * DESCRIPTION: set range of frames to skip for preview
9987  *
9988  * PARAMETERS :
9989  *   @start   : frameId to start skip
9990  *   @end     : frameId to stop skip
9991  *
9992  * RETURN     : None
9993  *==========================================================================*/
setDisplayFrameSkip(uint32_t start,uint32_t end)9994 void QCamera2HardwareInterface::setDisplayFrameSkip(uint32_t start,
9995         uint32_t end)
9996 {
9997     if (start == 0) {
9998         mFrameSkipStart = 0;
9999         mFrameSkipEnd = 0;
10000         return;
10001     }
10002     if ((mFrameSkipStart == 0) || (mFrameSkipStart > start)) {
10003         mFrameSkipStart = start;
10004     }
10005     if ((end == 0) || (end > mFrameSkipEnd)) {
10006         mFrameSkipEnd = end;
10007     }
10008 }
10009 
10010 /*===========================================================================
10011  * FUNCTION   : isDisplayFrameToSkip
10012  *
10013  * DESCRIPTION: function to determin if input frame falls under skip range
10014  *
10015  * PARAMETERS :
10016  *   @frameId : frameId to verify
10017  *
10018  * RETURN     : true : need to skip
10019  *              false: no need to skip
10020  *==========================================================================*/
isDisplayFrameToSkip(uint32_t frameId)10021 bool QCamera2HardwareInterface::isDisplayFrameToSkip(uint32_t frameId)
10022 {
10023     return ((mFrameSkipStart != 0) && (frameId >= mFrameSkipStart) &&
10024             (frameId <= mFrameSkipEnd || mFrameSkipEnd == 0)) ? TRUE : FALSE;
10025 }
10026 
10027 /*===========================================================================
10028  * FUNCTION   : prepareHardwareForSnapshot
10029  *
10030  * DESCRIPTION: prepare hardware for snapshot, such as LED
10031  *
10032  * PARAMETERS :
10033  *   @afNeeded: flag indicating if Auto Focus needs to be done during preparation
10034  *
10035  * RETURN     : int32_t type of status
10036  *              NO_ERROR  -- success
10037  *              none-zero failure code
10038  *==========================================================================*/
prepareHardwareForSnapshot(int32_t afNeeded)10039 int32_t QCamera2HardwareInterface::prepareHardwareForSnapshot(int32_t afNeeded)
10040 {
10041     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PREPARE_HW_FOR_SNAPSHOT);
10042     LOGI("[KPI Perf]: Send PREPARE SANSPHOT event");
10043     return mCameraHandle->ops->prepare_snapshot(mCameraHandle->camera_handle,
10044                                                 afNeeded);
10045 }
10046 
10047 /*===========================================================================
10048  * FUNCTION   : needFDMetadata
10049  *
10050  * DESCRIPTION: check whether we need process Face Detection metadata in this chanel
10051  *
10052  * PARAMETERS :
10053  *   @channel_type: channel type
10054  *
10055   * RETURN     : true: needed
10056  *              false: no need
10057  *==========================================================================*/
needFDMetadata(qcamera_ch_type_enum_t channel_type)10058 bool QCamera2HardwareInterface::needFDMetadata(qcamera_ch_type_enum_t channel_type)
10059 {
10060     //Note: Currently we only process ZSL channel
10061     bool value = false;
10062     if(channel_type == QCAMERA_CH_TYPE_ZSL){
10063         //check if FD requirement is enabled
10064         if(mParameters.isSnapshotFDNeeded() &&
10065            mParameters.isFaceDetectionEnabled()){
10066             value = true;
10067             LOGH("Face Detection metadata is required in ZSL mode.");
10068         }
10069     }
10070 
10071     return value;
10072 }
10073 
10074 /*===========================================================================
10075  * FUNCTION   : deferredWorkRoutine
10076  *
10077  * DESCRIPTION: data process routine that executes deferred tasks
10078  *
10079  * PARAMETERS :
10080  *   @data    : user data ptr (QCamera2HardwareInterface)
10081  *
10082  * RETURN     : None
10083  *==========================================================================*/
deferredWorkRoutine(void * obj)10084 void *QCamera2HardwareInterface::deferredWorkRoutine(void *obj)
10085 {
10086     int running = 1;
10087     int ret;
10088     uint8_t is_active = FALSE;
10089     int32_t job_status = 0;
10090 
10091     QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)obj;
10092     QCameraCmdThread *cmdThread = &pme->mDeferredWorkThread;
10093     cmdThread->setName("CAM_defrdWrk");
10094 
10095     do {
10096         do {
10097             ret = cam_sem_wait(&cmdThread->cmd_sem);
10098             if (ret != 0 && errno != EINVAL) {
10099                 LOGE("cam_sem_wait error (%s)",
10100                          strerror(errno));
10101                 return NULL;
10102             }
10103         } while (ret != 0);
10104 
10105         // we got notified about new cmd avail in cmd queue
10106         camera_cmd_type_t cmd = cmdThread->getCmd();
10107         LOGD("cmd: %d", cmd);
10108         switch (cmd) {
10109         case CAMERA_CMD_TYPE_START_DATA_PROC:
10110             LOGH("start data proc");
10111             is_active = TRUE;
10112             break;
10113         case CAMERA_CMD_TYPE_STOP_DATA_PROC:
10114             LOGH("stop data proc");
10115             is_active = FALSE;
10116             // signal cmd is completed
10117             cam_sem_post(&cmdThread->sync_sem);
10118             break;
10119         case CAMERA_CMD_TYPE_DO_NEXT_JOB:
10120             {
10121                 DefWork *dw =
10122                     reinterpret_cast<DefWork *>(pme->mCmdQueue.dequeue());
10123 
10124                 if ( NULL == dw ) {
10125                     LOGE("Invalid deferred work");
10126                     break;
10127                 }
10128 
10129                 switch( dw->cmd ) {
10130                 case CMD_DEF_ALLOCATE_BUFF:
10131                     {
10132                         QCameraChannel * pChannel = dw->args.allocArgs.ch;
10133 
10134                         if ( NULL == pChannel ) {
10135                             LOGE("Invalid deferred work channel");
10136                             job_status = BAD_VALUE;
10137                             break;
10138                         }
10139 
10140                         cam_stream_type_t streamType = dw->args.allocArgs.type;
10141                         LOGH("Deferred buffer allocation started for stream type: %d",
10142                                  streamType);
10143 
10144                         uint32_t iNumOfStreams = pChannel->getNumOfStreams();
10145                         QCameraStream *pStream = NULL;
10146                         for ( uint32_t i = 0; i < iNumOfStreams; ++i) {
10147                             pStream = pChannel->getStreamByIndex(i);
10148 
10149                             if ( NULL == pStream ) {
10150                                 job_status = BAD_VALUE;
10151                                 break;
10152                             }
10153 
10154                             if ( pStream->isTypeOf(streamType)) {
10155                                 if ( pStream->allocateBuffers() ) {
10156                                     LOGE("Error allocating buffers !!!");
10157                                     job_status =  NO_MEMORY;
10158                                     pme->sendEvtNotify(CAMERA_MSG_ERROR,
10159                                             CAMERA_ERROR_UNKNOWN, 0);
10160                                 }
10161                                 break;
10162                             }
10163                         }
10164                     }
10165                     break;
10166                 case CMD_DEF_PPROC_START:
10167                     {
10168                         int32_t ret = pme->getDefJobStatus(pme->mInitPProcJob);
10169                         if (ret != NO_ERROR) {
10170                             job_status = ret;
10171                             LOGE("PPROC Start failed");
10172                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
10173                                     CAMERA_ERROR_UNKNOWN, 0);
10174                             break;
10175                         }
10176                         QCameraChannel * pChannel = dw->args.pprocArgs;
10177                         assert(pChannel);
10178 
10179                         if (pme->m_postprocessor.start(pChannel) != NO_ERROR) {
10180                             LOGE("cannot start postprocessor");
10181                             job_status = BAD_VALUE;
10182                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
10183                                     CAMERA_ERROR_UNKNOWN, 0);
10184                         }
10185                     }
10186                     break;
10187                 case CMD_DEF_METADATA_ALLOC:
10188                     {
10189                         int32_t ret = pme->getDefJobStatus(pme->mParamAllocJob);
10190                         if (ret != NO_ERROR) {
10191                             job_status = ret;
10192                             LOGE("Metadata alloc failed");
10193                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
10194                                     CAMERA_ERROR_UNKNOWN, 0);
10195                             break;
10196                         }
10197                         pme->mMetadataMem = new QCameraMetadataStreamMemory(
10198                                 QCAMERA_ION_USE_CACHE);
10199 
10200                         if (pme->mMetadataMem == NULL) {
10201                             LOGE("Unable to allocate metadata buffers");
10202                             job_status = BAD_VALUE;
10203                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
10204                                     CAMERA_ERROR_UNKNOWN, 0);
10205                         } else {
10206                             int32_t rc = pme->mMetadataMem->allocate(
10207                                     dw->args.metadataAllocArgs.bufferCnt,
10208                                     dw->args.metadataAllocArgs.size,
10209                                     NON_SECURE);
10210                             if (rc < 0) {
10211                                 delete pme->mMetadataMem;
10212                                 pme->mMetadataMem = NULL;
10213                             }
10214                         }
10215                      }
10216                      break;
10217                 case CMD_DEF_CREATE_JPEG_SESSION:
10218                     {
10219                         QCameraChannel * pChannel = dw->args.pprocArgs;
10220                         assert(pChannel);
10221 
10222                         int32_t ret = pme->getDefJobStatus(pme->mReprocJob);
10223                         if (ret != NO_ERROR) {
10224                             job_status = ret;
10225                             LOGE("Jpeg create failed");
10226                             break;
10227                         }
10228 
10229                         if (pme->m_postprocessor.createJpegSession(pChannel)
10230                             != NO_ERROR) {
10231                             LOGE("cannot create JPEG session");
10232                             job_status = UNKNOWN_ERROR;
10233                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
10234                                     CAMERA_ERROR_UNKNOWN, 0);
10235                         }
10236                     }
10237                     break;
10238                 case CMD_DEF_PPROC_INIT:
10239                     {
10240                         int32_t rc = NO_ERROR;
10241 
10242                         jpeg_encode_callback_t jpegEvtHandle =
10243                                 dw->args.pprocInitArgs.jpeg_cb;
10244                         void* user_data = dw->args.pprocInitArgs.user_data;
10245                         QCameraPostProcessor *postProcessor =
10246                                 &(pme->m_postprocessor);
10247                         uint32_t cameraId = pme->mCameraId;
10248                         cam_capability_t *capability =
10249                                 gCamCapability[cameraId];
10250                         cam_padding_info_t padding_info;
10251                         cam_padding_info_t& cam_capability_padding_info =
10252                                 capability->padding_info;
10253 
10254                         if(!pme->mJpegClientHandle) {
10255                             rc = pme->initJpegHandle();
10256                             if (rc != NO_ERROR) {
10257                                 LOGE("Error!! creating JPEG handle failed");
10258                                 job_status = UNKNOWN_ERROR;
10259                                 pme->sendEvtNotify(CAMERA_MSG_ERROR,
10260                                         CAMERA_ERROR_UNKNOWN, 0);
10261                                 break;
10262                             }
10263                         }
10264                         LOGH("mJpegClientHandle : %d", pme->mJpegClientHandle);
10265 
10266                         rc = postProcessor->setJpegHandle(&pme->mJpegHandle,
10267                                 &pme->mJpegMpoHandle,
10268                                 pme->mJpegClientHandle);
10269                         if (rc != 0) {
10270                             LOGE("Error!! set JPEG handle failed");
10271                             job_status = UNKNOWN_ERROR;
10272                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
10273                                     CAMERA_ERROR_UNKNOWN, 0);
10274                             break;
10275                         }
10276 
10277                         /* get max pic size for jpeg work buf calculation*/
10278                         rc = postProcessor->init(jpegEvtHandle, user_data);
10279 
10280                         if (rc != NO_ERROR) {
10281                             LOGE("cannot init postprocessor");
10282                             job_status = UNKNOWN_ERROR;
10283                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
10284                                     CAMERA_ERROR_UNKNOWN, 0);
10285                             break;
10286                         }
10287 
10288                         // update padding info from jpeg
10289                         postProcessor->getJpegPaddingReq(padding_info);
10290                         if (cam_capability_padding_info.width_padding <
10291                                 padding_info.width_padding) {
10292                             cam_capability_padding_info.width_padding =
10293                                     padding_info.width_padding;
10294                         }
10295                         if (cam_capability_padding_info.height_padding <
10296                                 padding_info.height_padding) {
10297                             cam_capability_padding_info.height_padding =
10298                                     padding_info.height_padding;
10299                         }
10300                         if (cam_capability_padding_info.plane_padding !=
10301                                 padding_info.plane_padding) {
10302                             cam_capability_padding_info.plane_padding =
10303                                     mm_stream_calc_lcm(
10304                                     cam_capability_padding_info.plane_padding,
10305                                     padding_info.plane_padding);
10306                         }
10307                         if (cam_capability_padding_info.offset_info.offset_x
10308                                 != padding_info.offset_info.offset_x) {
10309                             cam_capability_padding_info.offset_info.offset_x =
10310                                     mm_stream_calc_lcm (
10311                                     cam_capability_padding_info.offset_info.offset_x,
10312                                     padding_info.offset_info.offset_x);
10313                         }
10314                         if (cam_capability_padding_info.offset_info.offset_y
10315                                 != padding_info.offset_info.offset_y) {
10316                             cam_capability_padding_info.offset_info.offset_y =
10317                             mm_stream_calc_lcm (
10318                                     cam_capability_padding_info.offset_info.offset_y,
10319                                     padding_info.offset_info.offset_y);
10320                         }
10321                     }
10322                     break;
10323                 case CMD_DEF_PARAM_ALLOC:
10324                     {
10325                         int32_t rc = NO_ERROR;
10326                         if (pme->isDualCamera()) {
10327                             rc = pme->mParameters.allocate(MM_CAMERA_MAX_CAM_CNT);
10328                         } else {
10329                             rc = pme->mParameters.allocate();
10330                         }
10331                         // notify routine would not be initialized by this time.
10332                         // So, just update error job status
10333                         if (rc != NO_ERROR) {
10334                             job_status = rc;
10335                             LOGE("Param allocation failed");
10336                             break;
10337                         }
10338                     }
10339                     break;
10340                 case CMD_DEF_PARAM_INIT:
10341                     {
10342                         int32_t rc = pme->getDefJobStatus(pme->mParamAllocJob);
10343                         if (rc != NO_ERROR) {
10344                             job_status = rc;
10345                             LOGE("Param init failed");
10346                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
10347                                     CAMERA_ERROR_UNKNOWN, 0);
10348                             break;
10349                         }
10350 
10351                         uint32_t camId = pme->mCameraId;
10352                         cam_capability_t * cap = gCamCapability[camId];
10353 
10354                         if (pme->mCameraHandle == NULL) {
10355                             LOGE("Camera handle is null");
10356                             job_status = BAD_VALUE;
10357                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
10358                                     CAMERA_ERROR_UNKNOWN, 0);
10359                             break;
10360                         }
10361 
10362                         // Now PostProc need calibration data as initialization
10363                         // time for jpeg_open and calibration data is a
10364                         // get param for now, so params needs to be initialized
10365                         // before postproc init
10366                         rc = pme->mParameters.init(cap,
10367                                 pme->mCameraHandle,
10368                                 pme, pme->m_pFovControl);
10369                         if (rc != 0) {
10370                             job_status = UNKNOWN_ERROR;
10371                             LOGE("Parameter Initialization failed");
10372                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
10373                                     CAMERA_ERROR_UNKNOWN, 0);
10374                             break;
10375                         }
10376 
10377                         // Get related cam calibration only in
10378                         // dual camera mode
10379                         if (pme->getRelatedCamSyncInfo()->sync_control ==
10380                                 CAM_SYNC_RELATED_SENSORS_ON) {
10381                             rc = pme->mParameters.getRelatedCamCalibration(
10382                                 &(pme->mJpegMetadata.otp_calibration_data));
10383                             LOGD("Dumping Calibration Data Version Id %f rc %d",
10384                                     pme->mJpegMetadata.otp_calibration_data.calibration_format_version,
10385                                     rc);
10386                             if (rc != 0) {
10387                                 job_status = UNKNOWN_ERROR;
10388                                 LOGE("getRelatedCamCalibration failed");
10389                                 pme->sendEvtNotify(CAMERA_MSG_ERROR,
10390                                         CAMERA_ERROR_UNKNOWN, 0);
10391                                 break;
10392                             }
10393                             pme->m_bRelCamCalibValid = true;
10394                         }
10395 
10396                         pme->mJpegMetadata.sensor_mount_angle =
10397                             cap->sensor_mount_angle;
10398                         pme->mJpegMetadata.default_sensor_flip = FLIP_NONE;
10399 
10400                         pme->mParameters.setMinPpMask(
10401                             cap->qcom_supported_feature_mask);
10402                         pme->mExifParams.debug_params =
10403                                 (mm_jpeg_debug_exif_params_t *)
10404                                 malloc(sizeof(mm_jpeg_debug_exif_params_t));
10405                         if (!pme->mExifParams.debug_params) {
10406                             LOGE("Out of Memory. Allocation failed for "
10407                                     "3A debug exif params");
10408                             job_status = NO_MEMORY;
10409                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
10410                                     CAMERA_ERROR_UNKNOWN, 0);
10411                             break;
10412                         }
10413                         memset(pme->mExifParams.debug_params, 0,
10414                                 sizeof(mm_jpeg_debug_exif_params_t));
10415                     }
10416                     break;
10417                 case CMD_DEF_GENERIC:
10418                     {
10419                         BackgroundTask *bgTask = dw->args.genericArgs;
10420                         job_status = bgTask->bgFunction(bgTask->bgArgs);
10421                     }
10422                     break;
10423                 default:
10424                     LOGE("Incorrect command : %d", dw->cmd);
10425                 }
10426 
10427                 pme->dequeueDeferredWork(dw, job_status);
10428             }
10429             break;
10430         case CAMERA_CMD_TYPE_EXIT:
10431             running = 0;
10432             break;
10433         default:
10434             break;
10435         }
10436     } while (running);
10437 
10438     return NULL;
10439 }
10440 
10441 /*===========================================================================
10442  * FUNCTION   : queueDeferredWork
10443  *
10444  * DESCRIPTION: function which queues deferred tasks
10445  *
10446  * PARAMETERS :
10447  *   @cmd     : deferred task
10448  *   @args    : deferred task arguments
10449  *
10450  * RETURN     : job id of deferred job
10451  *            : 0 in case of error
10452  *==========================================================================*/
queueDeferredWork(DeferredWorkCmd cmd,DeferWorkArgs args)10453 uint32_t QCamera2HardwareInterface::queueDeferredWork(DeferredWorkCmd cmd,
10454                                                       DeferWorkArgs args)
10455 {
10456     Mutex::Autolock l(mDefLock);
10457     for (int32_t i = 0; i < MAX_ONGOING_JOBS; ++i) {
10458         if (mDefOngoingJobs[i].mDefJobId == 0) {
10459             DefWork *dw = new DefWork(cmd, sNextJobId, args);
10460             if (!dw) {
10461                 LOGE("out of memory.");
10462                 return 0;
10463             }
10464             if (mCmdQueue.enqueue(dw)) {
10465                 mDefOngoingJobs[i].mDefJobId = sNextJobId++;
10466                 mDefOngoingJobs[i].mDefJobStatus = 0;
10467                 if (sNextJobId == 0) { // handle overflow
10468                     sNextJobId = 1;
10469                 }
10470                 mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB,
10471                         FALSE,
10472                         FALSE);
10473                 return mDefOngoingJobs[i].mDefJobId;
10474             } else {
10475                 LOGD("Command queue not active! cmd = %d", cmd);
10476                 delete dw;
10477                 return 0;
10478             }
10479         }
10480     }
10481     return 0;
10482 }
10483 
10484 /*===========================================================================
10485  * FUNCTION   : initJpegHandle
10486  *
10487  * DESCRIPTION: Opens JPEG client and gets a handle.
10488  *                     Sends Dual cam calibration info if present
10489  *
10490  * RETURN     : int32_t type of status
10491  *              NO_ERROR  -- success
10492  *              none-zero failure code
10493  *==========================================================================*/
initJpegHandle()10494 int32_t QCamera2HardwareInterface::initJpegHandle() {
10495     // Check if JPEG client handle is present
10496     LOGH("E");
10497     if(!mJpegClientHandle) {
10498         mm_dimension max_size = {0, 0};
10499         cam_dimension_t size;
10500 
10501         mParameters.getMaxPicSize(size);
10502         max_size.w = size.width;
10503         max_size.h = size.height;
10504 
10505         if (getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
10506             if (m_bRelCamCalibValid) {
10507                 mJpegClientHandle = jpeg_open(&mJpegHandle, &mJpegMpoHandle,
10508                         max_size, &mJpegMetadata);
10509             } else {
10510                 mJpegClientHandle =  jpeg_open(&mJpegHandle, &mJpegMpoHandle,
10511                         max_size, NULL);
10512             }
10513         } else {
10514             mJpegClientHandle = jpeg_open(&mJpegHandle, NULL, max_size, NULL);
10515         }
10516         if (!mJpegClientHandle) {
10517             LOGE("Error !! jpeg_open failed!! ");
10518             return UNKNOWN_ERROR;
10519         }
10520         // Set JPEG initialized as true to signify that this camera
10521         // has initialized the handle
10522         mJpegHandleOwner = true;
10523     }
10524     LOGH("X mJpegHandleOwner: %d, mJpegClientHandle: %d camera id: %d",
10525              mJpegHandleOwner, mJpegClientHandle, mCameraId);
10526     return NO_ERROR;
10527 }
10528 
10529 /*===========================================================================
10530  * FUNCTION   : deinitJpegHandle
10531  *
10532  * DESCRIPTION: Closes JPEG client using handle
10533  *
10534  * RETURN     : int32_t type of status
10535  *              NO_ERROR  -- success
10536  *              none-zero failure code
10537  *==========================================================================*/
deinitJpegHandle()10538 int32_t QCamera2HardwareInterface::deinitJpegHandle() {
10539     int32_t rc = NO_ERROR;
10540     LOGH("E");
10541     // Check if JPEG client handle is present and inited by this camera
10542     if(mJpegHandleOwner && mJpegClientHandle) {
10543         rc = mJpegHandle.close(mJpegClientHandle);
10544         if (rc != NO_ERROR) {
10545             LOGE("Error!! Closing mJpegClientHandle: %d failed",
10546                      mJpegClientHandle);
10547         }
10548         memset(&mJpegHandle, 0, sizeof(mJpegHandle));
10549         memset(&mJpegMpoHandle, 0, sizeof(mJpegMpoHandle));
10550         mJpegHandleOwner = false;
10551     }
10552     mJpegClientHandle = 0;
10553     LOGH("X rc = %d", rc);
10554     return rc;
10555 }
10556 
10557 /*===========================================================================
10558  * FUNCTION   : setJpegHandleInfo
10559  *
10560  * DESCRIPTION: sets JPEG client handle info
10561  *
10562  * PARAMETERS:
10563  *                  @ops                    : JPEG ops
10564  *                  @mpo_ops             : Jpeg MPO ops
10565  *                  @pJpegClientHandle : o/p Jpeg Client Handle
10566  *
10567  * RETURN     : int32_t type of status
10568  *              NO_ERROR  -- success
10569  *              none-zero failure code
10570  *==========================================================================*/
setJpegHandleInfo(mm_jpeg_ops_t * ops,mm_jpeg_mpo_ops_t * mpo_ops,uint32_t pJpegClientHandle)10571 int32_t QCamera2HardwareInterface::setJpegHandleInfo(mm_jpeg_ops_t *ops,
10572         mm_jpeg_mpo_ops_t *mpo_ops, uint32_t pJpegClientHandle) {
10573 
10574     if (pJpegClientHandle && ops && mpo_ops) {
10575         LOGH("Setting JPEG client handle %d",
10576                 pJpegClientHandle);
10577         memcpy(&mJpegHandle, ops, sizeof(mm_jpeg_ops_t));
10578         memcpy(&mJpegMpoHandle, mpo_ops, sizeof(mm_jpeg_mpo_ops_t));
10579         mJpegClientHandle = pJpegClientHandle;
10580         return NO_ERROR;
10581     }
10582     else {
10583         LOGE("Error!! No Handle found: %d",
10584                 pJpegClientHandle);
10585         return BAD_VALUE;
10586     }
10587 }
10588 
10589 /*===========================================================================
10590  * FUNCTION   : getJpegHandleInfo
10591  *
10592  * DESCRIPTION: gets JPEG client handle info
10593  *
10594  * PARAMETERS:
10595  *                  @ops                    : JPEG ops
10596  *                  @mpo_ops             : Jpeg MPO ops
10597  *                  @pJpegClientHandle : o/p Jpeg Client Handle
10598  *
10599  * RETURN     : int32_t type of status
10600  *              NO_ERROR  -- success
10601  *              none-zero failure code
10602  *==========================================================================*/
getJpegHandleInfo(mm_jpeg_ops_t * ops,mm_jpeg_mpo_ops_t * mpo_ops,uint32_t * pJpegClientHandle)10603 int32_t QCamera2HardwareInterface::getJpegHandleInfo(mm_jpeg_ops_t *ops,
10604         mm_jpeg_mpo_ops_t *mpo_ops, uint32_t *pJpegClientHandle) {
10605 
10606     if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
10607         LOGE("Init PProc Deferred work failed");
10608         return UNKNOWN_ERROR;
10609     }
10610     // Copy JPEG ops if present
10611     if (ops && mpo_ops && pJpegClientHandle) {
10612         memcpy(ops, &mJpegHandle, sizeof(mm_jpeg_ops_t));
10613         memcpy(mpo_ops, &mJpegMpoHandle, sizeof(mm_jpeg_mpo_ops_t));
10614         *pJpegClientHandle = mJpegClientHandle;
10615         LOGH("Getting JPEG client handle %d",
10616                 pJpegClientHandle);
10617         return NO_ERROR;
10618     } else {
10619         return BAD_VALUE;
10620     }
10621 }
10622 
10623 /*===========================================================================
10624  * FUNCTION   : dequeueDeferredWork
10625  *
10626  * DESCRIPTION: function which dequeues deferred tasks
10627  *
10628  * PARAMETERS :
10629  *   @dw      : deferred work
10630  *   @jobStatus: deferred task job status
10631  *
10632  * RETURN     : int32_t type of status
10633  *              NO_ERROR  -- success
10634  *              none-zero failure code
10635  *==========================================================================*/
dequeueDeferredWork(DefWork * dw,int32_t jobStatus)10636 uint32_t QCamera2HardwareInterface::dequeueDeferredWork(DefWork* dw, int32_t jobStatus)
10637 {
10638     Mutex::Autolock l(mDefLock);
10639     for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) {
10640         if (mDefOngoingJobs[i].mDefJobId == dw->id) {
10641             if (jobStatus != NO_ERROR) {
10642                 mDefOngoingJobs[i].mDefJobStatus = jobStatus;
10643                 LOGH("updating job status %d for id %d",
10644                          jobStatus, dw->id);
10645             } else {
10646                 mDefOngoingJobs[i].mDefJobId = 0;
10647                 mDefOngoingJobs[i].mDefJobStatus = 0;
10648             }
10649             delete dw;
10650             mDefCond.broadcast();
10651             return NO_ERROR;
10652         }
10653     }
10654 
10655     return UNKNOWN_ERROR;
10656 }
10657 
10658 /*===========================================================================
10659  * FUNCTION   : getDefJobStatus
10660  *
10661  * DESCRIPTION: Gets if a deferred task is success/fail
10662  *
10663  * PARAMETERS :
10664  *   @job_id  : deferred task id
10665  *
10666  * RETURN     : NO_ERROR if the job success, otherwise false
10667  *
10668  * PRECONDITION : mDefLock is held by current thread
10669  *==========================================================================*/
getDefJobStatus(uint32_t & job_id)10670 int32_t QCamera2HardwareInterface::getDefJobStatus(uint32_t &job_id)
10671 {
10672     for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) {
10673         if (mDefOngoingJobs[i].mDefJobId == job_id) {
10674             if ( NO_ERROR != mDefOngoingJobs[i].mDefJobStatus ) {
10675                 LOGE("job_id (%d) was failed", job_id);
10676                 return mDefOngoingJobs[i].mDefJobStatus;
10677             }
10678             else
10679                 return NO_ERROR;
10680         }
10681     }
10682     return NO_ERROR;
10683 }
10684 
10685 
10686 /*===========================================================================
10687  * FUNCTION   : checkDeferredWork
10688  *
10689  * DESCRIPTION: checks if a deferred task is in progress
10690  *
10691  * PARAMETERS :
10692  *   @job_id  : deferred task id
10693  *
10694  * RETURN     : true if the task exists, otherwise false
10695  *
10696  * PRECONDITION : mDefLock is held by current thread
10697  *==========================================================================*/
checkDeferredWork(uint32_t & job_id)10698 bool QCamera2HardwareInterface::checkDeferredWork(uint32_t &job_id)
10699 {
10700     for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) {
10701         if (mDefOngoingJobs[i].mDefJobId == job_id) {
10702             return (NO_ERROR == mDefOngoingJobs[i].mDefJobStatus);
10703         }
10704     }
10705     return false;
10706 }
10707 
10708 /*===========================================================================
10709  * FUNCTION   : waitDeferredWork
10710  *
10711  * DESCRIPTION: waits for a deferred task to finish
10712  *
10713  * PARAMETERS :
10714  *   @job_id  : deferred task id
10715  *
10716  * RETURN     : int32_t type of status
10717  *              NO_ERROR  -- success
10718  *              none-zero failure code
10719  *==========================================================================*/
waitDeferredWork(uint32_t & job_id)10720 int32_t QCamera2HardwareInterface::waitDeferredWork(uint32_t &job_id)
10721 {
10722     Mutex::Autolock l(mDefLock);
10723 
10724     if (job_id == 0) {
10725         LOGD("Invalid job id %d", job_id);
10726         return NO_ERROR;
10727     }
10728 
10729     while (checkDeferredWork(job_id) == true ) {
10730         mDefCond.waitRelative(mDefLock, CAMERA_DEFERRED_THREAD_TIMEOUT);
10731     }
10732     return getDefJobStatus(job_id);
10733 }
10734 
10735 /*===========================================================================
10736  * FUNCTION   : scheduleBackgroundTask
10737  *
10738  * DESCRIPTION: Run a requested task in the deferred thread
10739  *
10740  * PARAMETERS :
10741  *   @bgTask  : Task to perform in the background
10742  *
10743  * RETURN     : job id of deferred job
10744  *            : 0 in case of error
10745  *==========================================================================*/
scheduleBackgroundTask(BackgroundTask * bgTask)10746 uint32_t QCamera2HardwareInterface::scheduleBackgroundTask(BackgroundTask* bgTask)
10747 {
10748     DeferWorkArgs args;
10749     memset(&args, 0, sizeof(DeferWorkArgs));
10750     args.genericArgs = bgTask;
10751 
10752     return queueDeferredWork(CMD_DEF_GENERIC, args);
10753 }
10754 
10755 /*===========================================================================
10756  * FUNCTION   : waitForBackgroundTask
10757  *
10758  * DESCRIPTION: Wait for a background task to complete
10759  *
10760  * PARAMETERS :
10761  *   @taskId  : Task id to wait for
10762  *
10763  * RETURN     : int32_t type of status
10764  *              NO_ERROR  -- success
10765  *              none-zero failure code
10766  *==========================================================================*/
waitForBackgroundTask(uint32_t & taskId)10767 int32_t QCamera2HardwareInterface::waitForBackgroundTask(uint32_t& taskId)
10768 {
10769     return waitDeferredWork(taskId);
10770 }
10771 
10772 /*===========================================================================
10773  * FUNCTION   : needDeferedAllocation
10774  *
10775  * DESCRIPTION: Function to decide background task for streams
10776  *
10777  * PARAMETERS :
10778  *   @stream_type  : stream type
10779  *
10780  * RETURN     : true - if background task is needed
10781  *              false -  if background task is NOT needed
10782  *==========================================================================*/
needDeferred(cam_stream_type_t stream_type)10783 bool QCamera2HardwareInterface::needDeferred(cam_stream_type_t stream_type)
10784 {
10785     if ((stream_type == CAM_STREAM_TYPE_PREVIEW && mPreviewWindow == NULL)
10786             || (stream_type == CAM_STREAM_TYPE_ANALYSIS)) {
10787         return FALSE;
10788     }
10789 
10790     if ((stream_type == CAM_STREAM_TYPE_RAW)
10791             && (mParameters.getofflineRAW())) {
10792         return FALSE;
10793     }
10794 
10795     if ((stream_type == CAM_STREAM_TYPE_SNAPSHOT)
10796             && (!mParameters.getRecordingHintValue())){
10797         return TRUE;
10798     }
10799 
10800     if ((stream_type == CAM_STREAM_TYPE_PREVIEW)
10801             || (stream_type == CAM_STREAM_TYPE_METADATA)
10802             || (stream_type == CAM_STREAM_TYPE_RAW)
10803             || (stream_type == CAM_STREAM_TYPE_POSTVIEW)) {
10804         return TRUE;
10805     }
10806 
10807     if (stream_type == CAM_STREAM_TYPE_VIDEO) {
10808         return FALSE;
10809     }
10810     return FALSE;
10811 }
10812 
10813 /*===========================================================================
10814  * FUNCTION   : needSyncCB
10815  *
10816  * DESCRIPTION: Decide syncronous callback per stream
10817  *
10818  * PARAMETERS :
10819  *  @stream_type: stream type
10820  *
10821  * RETURN     : true - if background task is needed
10822  *              false -  if background task is NOT needed
10823  *==========================================================================*/
needSyncCB(cam_stream_type_t stream_type)10824 bool QCamera2HardwareInterface::needSyncCB(cam_stream_type_t stream_type)
10825 {
10826 #ifdef TARGET_TS_MAKEUP
10827     int whiteLevel, cleanLevel;
10828     if(mParameters.getTsMakeupInfo(whiteLevel, cleanLevel) == TRUE) {
10829         return FALSE;
10830     }
10831 #endif
10832 
10833     char value[PROPERTY_VALUE_MAX];
10834     property_get("persist.camera.preview.sync_cb", value, "1");
10835     if ((atoi(value) == 1) && (stream_type == CAM_STREAM_TYPE_PREVIEW)) {
10836         return TRUE;
10837     }
10838     return FALSE;
10839 }
10840 
10841 /*===========================================================================
10842  * FUNCTION   : isRegularCapture
10843  *
10844  * DESCRIPTION: Check configuration for regular catpure
10845  *
10846  * PARAMETERS :
10847  *
10848  * RETURN     : true - regular capture
10849  *              false - other type of capture
10850  *==========================================================================*/
isRegularCapture()10851 bool QCamera2HardwareInterface::isRegularCapture()
10852 {
10853     bool ret = false;
10854 
10855     if (numOfSnapshotsExpected() == 1 &&
10856         !isLongshotEnabled() &&
10857         !mParameters.isHDREnabled() &&
10858         !mParameters.getRecordingHintValue() &&
10859         !isZSLMode() && (!mParameters.getofflineRAW()|| mParameters.getQuadraCfa())) {
10860             ret = true;
10861     }
10862     return ret;
10863 }
10864 
10865 /*===========================================================================
10866  * FUNCTION   : needOfflineReprocessing
10867  *
10868  * DESCRIPTION: Check for offline reprocessing
10869  *
10870  * PARAMETERS :
10871  *
10872  * RETURN     : true - regular capture
10873  *              false - other type of capture
10874  *==========================================================================*/
needOfflineReprocessing()10875 bool QCamera2HardwareInterface::needOfflineReprocessing()
10876 {
10877     bool ret = false;
10878     if (isRegularCapture()
10879             || isDualCamera()) {
10880         ret = true;
10881     }
10882     return ret;
10883 }
10884 
10885 /*===========================================================================
10886  * FUNCTION   : getLogLevel
10887  *
10888  * DESCRIPTION: Reads the log level property into a variable
10889  *
10890  * PARAMETERS :
10891  *   None
10892  *
10893  * RETURN     :
10894  *   None
10895  *==========================================================================*/
getLogLevel()10896 void QCamera2HardwareInterface::getLogLevel()
10897 {
10898     char prop[PROPERTY_VALUE_MAX];
10899 
10900     property_get("persist.camera.kpi.debug", prop, "1");
10901     gKpiDebugLevel = atoi(prop);
10902     return;
10903 }
10904 
10905 /*===========================================================================
10906  * FUNCTION   : getSensorType
10907  *
10908  * DESCRIPTION: Returns the type of sensor being used whether YUV or Bayer
10909  *
10910  * PARAMETERS :
10911  *   None
10912  *
10913  * RETURN     : Type of sensor - bayer or YUV
10914  *
10915  *==========================================================================*/
getSensorType()10916 cam_sensor_t QCamera2HardwareInterface::getSensorType()
10917 {
10918     return gCamCapability[mCameraId]->sensor_type.sens_type;
10919 }
10920 
10921 /*===========================================================================
10922  * FUNCTION   : startRAWChannel
10923  *
10924  * DESCRIPTION: start RAW Channel
10925  *
10926  * PARAMETERS :
10927  *   @pChannel  : Src channel to link this RAW channel.
10928  *
10929  * RETURN     : int32_t type of status
10930  *              NO_ERROR  -- success
10931  *              none-zero failure code
10932  *==========================================================================*/
startRAWChannel(QCameraChannel * pMetaChannel)10933 int32_t QCamera2HardwareInterface::startRAWChannel(QCameraChannel *pMetaChannel)
10934 {
10935     int32_t rc = NO_ERROR;
10936     QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_RAW];
10937     if ((NULL != pChannel) && (mParameters.getofflineRAW())) {
10938         // Find and try to link a metadata stream from preview channel
10939         QCameraStream *pMetaStream = NULL;
10940 
10941         if (pMetaChannel != NULL) {
10942             uint32_t streamNum = pMetaChannel->getNumOfStreams();
10943             QCameraStream *pStream = NULL;
10944             for (uint32_t i = 0 ; i < streamNum ; i++ ) {
10945                 pStream = pMetaChannel->getStreamByIndex(i);
10946                 if ((NULL != pStream) &&
10947                         (CAM_STREAM_TYPE_METADATA == pStream->getMyType())) {
10948                     pMetaStream = pStream;
10949                     break;
10950                 }
10951             }
10952 
10953             if (NULL != pMetaStream) {
10954                 rc = pChannel->linkStream(pMetaChannel, pMetaStream);
10955                 if (NO_ERROR != rc) {
10956                     LOGE("Metadata stream link failed %d", rc);
10957                 }
10958             }
10959         }
10960         rc = pChannel->start();
10961     }
10962     return rc;
10963 }
10964 
10965 /*===========================================================================
10966  * FUNCTION   : startRecording
10967  *
10968  * DESCRIPTION: start recording impl
10969  *
10970  * PARAMETERS : none
10971  *
10972  * RETURN     : int32_t type of status
10973  *              NO_ERROR  -- success
10974  *              none-zero failure code
10975  *==========================================================================*/
stopRAWChannel()10976 int32_t QCamera2HardwareInterface::stopRAWChannel()
10977 {
10978     int32_t rc = NO_ERROR;
10979     rc = stopChannel(QCAMERA_CH_TYPE_RAW);
10980     return rc;
10981 }
10982 
10983 /*===========================================================================
10984  * FUNCTION   : isLowPowerMode
10985  *
10986  * DESCRIPTION: Returns TRUE if low power mode settings are to be applied for video recording
10987  *
10988  * PARAMETERS :
10989  *   None
10990  *
10991  * RETURN     : TRUE/FALSE
10992  *
10993  *==========================================================================*/
isLowPowerMode()10994 bool QCamera2HardwareInterface::isLowPowerMode()
10995 {
10996     cam_dimension_t dim;
10997     mParameters.getStreamDimension(CAM_STREAM_TYPE_VIDEO, dim);
10998 
10999     char prop[PROPERTY_VALUE_MAX];
11000     property_get("camera.lowpower.record.enable", prop, "0");
11001     int enable = atoi(prop);
11002 
11003     //Enable low power mode if :
11004     //1. Video resolution is 2k (2048x1080) or above and
11005     //2. camera.lowpower.record.enable is set
11006 
11007     bool isLowpower = mParameters.getRecordingHintValue() && enable
11008             && ((dim.width * dim.height) >= (2048 * 1080));
11009     return isLowpower;
11010 }
11011 
11012 /*===========================================================================
11013  * FUNCTION   : getBootToMonoTimeOffset
11014  *
11015  * DESCRIPTION: Calculate offset that is used to convert from
11016  *              clock domain of boot to monotonic
11017  *
11018  * PARAMETERS :
11019  *   None
11020  *
11021  * RETURN     : clock offset between boottime and monotonic time.
11022  *
11023  *==========================================================================*/
getBootToMonoTimeOffset()11024 nsecs_t QCamera2HardwareInterface::getBootToMonoTimeOffset()
11025 {
11026     // try three times to get the clock offset, choose the one
11027     // with the minimum gap in measurements.
11028     const int tries = 3;
11029     nsecs_t bestGap, measured;
11030     for (int i = 0; i < tries; ++i) {
11031         const nsecs_t tmono = systemTime(SYSTEM_TIME_MONOTONIC);
11032         const nsecs_t tbase = systemTime(SYSTEM_TIME_BOOTTIME);
11033         const nsecs_t tmono2 = systemTime(SYSTEM_TIME_MONOTONIC);
11034         const nsecs_t gap = tmono2 - tmono;
11035         if (i == 0 || gap < bestGap) {
11036             bestGap = gap;
11037             measured = tbase - ((tmono + tmono2) >> 1);
11038         }
11039     }
11040     return measured;
11041 }
11042 
11043 /*===========================================================================
11044  * FUNCTION   : fillDualCameraFOVControl
11045  *
11046  * DESCRIPTION: Function to process FOV ctrl event from statemachine thread.
11047  *
11048  * PARAMETERS : none
11049  *
11050  * RETURN     : none
11051  *==========================================================================*/
fillDualCameraFOVControl()11052 void QCamera2HardwareInterface::fillDualCameraFOVControl()
11053 {
11054     qcamera_sm_internal_evt_payload_t *payload =
11055        (qcamera_sm_internal_evt_payload_t *)
11056        malloc(sizeof(qcamera_sm_internal_evt_payload_t));
11057     if (NULL != payload) {
11058         memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
11059         payload->evt_type = QCAMERA_INTERNAL_EVT_DUAL_CAMERA_FOV_CONTROL;
11060         int32_t rc = processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
11061         if (rc != NO_ERROR) {
11062             LOGE("processEvt Dual camera fill FOV control failed");
11063             free(payload);
11064             payload = NULL;
11065         }
11066     } else {
11067         LOGE("No memory for Dual camera fill FOV control event");
11068     }
11069 }
11070 
11071 }; // namespace qcamera
11072