1 /* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 *     * Redistributions of source code must retain the above copyright
7 *       notice, this list of conditions and the following disclaimer.
8 *     * Redistributions in binary form must reproduce the above
9 *       copyright notice, this list of conditions and the following
10 *       disclaimer in the documentation and/or other materials provided
11 *       with the distribution.
12 *     * Neither the name of The Linux Foundation nor the names of its
13 *       contributors may be used to endorse or promote products derived
14 *       from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29 
30 #define LOG_TAG "QCamera2HWI"
31 
32 // To remove
33 #include <cutils/properties.h>
34 
35 // System definitions
36 #include <utils/Errors.h>
37 #include <dlfcn.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include "gralloc_priv.h"
41 #include "native_handle.h"
42 
43 // Camera definitions
44 #include "android/QCamera2External.h"
45 #include "QCamera2HWI.h"
46 #include "QCameraBufferMaps.h"
47 #include "QCameraFlash.h"
48 #include "QCameraTrace.h"
49 
50 extern "C" {
51 #include "mm_camera_dbg.h"
52 }
53 
54 #define MAP_TO_DRIVER_COORDINATE(val, base, scale, offset) \
55     ((int32_t)val * (int32_t)scale / (int32_t)base + (int32_t)offset)
56 #define CAMERA_MIN_STREAMING_BUFFERS     3
57 #define EXTRA_ZSL_PREVIEW_STREAM_BUF     2
58 #define CAMERA_MIN_JPEG_ENCODING_BUFFERS 2
59 #define CAMERA_MIN_VIDEO_BUFFERS         9
60 #define CAMERA_MIN_CALLBACK_BUFFERS      5
61 #define CAMERA_LONGSHOT_STAGES           4
62 #define CAMERA_MIN_CAMERA_BATCH_BUFFERS  6
63 #define CAMERA_ISP_PING_PONG_BUFFERS     2
64 #define MIN_UNDEQUEUED_BUFFERS           1 // This is required if preview window is not set
65 #define CAMERA_MIN_DISPLAY_BUFFERS       2
66 #define CAMERA_DEFAULT_FPS               30000
67 
68 #define HDR_CONFIDENCE_THRESHOLD 0.4
69 
70 #define CAMERA_OPEN_PERF_TIME_OUT 500 // 500 milliseconds
71 
72 // Very long wait, just to be sure we don't deadlock
73 #define CAMERA_DEFERRED_THREAD_TIMEOUT 5000000000 // 5 seconds
74 #define CAMERA_DEFERRED_MAP_BUF_TIMEOUT 2000000000 // 2 seconds
75 #define CAMERA_MIN_METADATA_BUFFERS 10 // Need at least 10 for ZSL snapshot
76 #define CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS 5
77 #define CAMERA_MAX_PARAM_APPLY_DELAY 3
78 
79 namespace qcamera {
80 
81 extern cam_capability_t *gCamCapability[MM_CAMERA_MAX_NUM_SENSORS];
82 extern pthread_mutex_t gCamLock;
83 volatile uint32_t gCamHalLogLevel = 1;
84 extern uint8_t gNumCameraSessions;
85 uint32_t QCamera2HardwareInterface::sNextJobId = 1;
86 
87 camera_device_ops_t QCamera2HardwareInterface::mCameraOps = {
88     .set_preview_window =        QCamera2HardwareInterface::set_preview_window,
89     .set_callbacks =             QCamera2HardwareInterface::set_CallBacks,
90     .enable_msg_type =           QCamera2HardwareInterface::enable_msg_type,
91     .disable_msg_type =          QCamera2HardwareInterface::disable_msg_type,
92     .msg_type_enabled =          QCamera2HardwareInterface::msg_type_enabled,
93 
94     .start_preview =             QCamera2HardwareInterface::start_preview,
95     .stop_preview =              QCamera2HardwareInterface::stop_preview,
96     .preview_enabled =           QCamera2HardwareInterface::preview_enabled,
97     .store_meta_data_in_buffers= QCamera2HardwareInterface::store_meta_data_in_buffers,
98 
99     .start_recording =           QCamera2HardwareInterface::start_recording,
100     .stop_recording =            QCamera2HardwareInterface::stop_recording,
101     .recording_enabled =         QCamera2HardwareInterface::recording_enabled,
102     .release_recording_frame =   QCamera2HardwareInterface::release_recording_frame,
103 
104     .auto_focus =                QCamera2HardwareInterface::auto_focus,
105     .cancel_auto_focus =         QCamera2HardwareInterface::cancel_auto_focus,
106 
107     .take_picture =              QCamera2HardwareInterface::take_picture,
108     .cancel_picture =            QCamera2HardwareInterface::cancel_picture,
109 
110     .set_parameters =            QCamera2HardwareInterface::set_parameters,
111     .get_parameters =            QCamera2HardwareInterface::get_parameters,
112     .put_parameters =            QCamera2HardwareInterface::put_parameters,
113     .send_command =              QCamera2HardwareInterface::send_command,
114 
115     .release =                   QCamera2HardwareInterface::release,
116     .dump =                      QCamera2HardwareInterface::dump,
117 };
118 
119 /*===========================================================================
120  * FUNCTION   : set_preview_window
121  *
122  * DESCRIPTION: set preview window.
123  *
124  * PARAMETERS :
125  *   @device  : ptr to camera device struct
126  *   @window  : window ops table
127  *
128  * RETURN     : int32_t type of status
129  *              NO_ERROR  -- success
130  *              none-zero failure code
131  *==========================================================================*/
set_preview_window(struct camera_device * device,struct preview_stream_ops * window)132 int QCamera2HardwareInterface::set_preview_window(struct camera_device *device,
133         struct preview_stream_ops *window)
134 {
135     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_SET_PREVIEW_WINDOW);
136     int rc = NO_ERROR;
137     QCamera2HardwareInterface *hw =
138         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
139     if (!hw) {
140         LOGE("NULL camera device");
141         return BAD_VALUE;
142     }
143     LOGD("E camera id %d window = %p", hw->getCameraId(), window);
144 
145     hw->lockAPI();
146     qcamera_api_result_t apiResult;
147     rc = hw->processAPI(QCAMERA_SM_EVT_SET_PREVIEW_WINDOW, (void *)window);
148     if (rc == NO_ERROR) {
149         hw->waitAPIResult(QCAMERA_SM_EVT_SET_PREVIEW_WINDOW, &apiResult);
150         rc = apiResult.status;
151     }
152     hw->unlockAPI();
153     LOGD("X camera id %d", hw->getCameraId());
154 
155     return rc;
156 }
157 
158 /*===========================================================================
159  * FUNCTION   : set_CallBacks
160  *
161  * DESCRIPTION: set callbacks for notify and data
162  *
163  * PARAMETERS :
164  *   @device     : ptr to camera device struct
165  *   @notify_cb  : notify cb
166  *   @data_cb    : data cb
167  *   @data_cb_timestamp  : video data cd with timestamp
168  *   @get_memory : ops table for request gralloc memory
169  *   @user       : user data ptr
170  *
171  * RETURN     : none
172  *==========================================================================*/
set_CallBacks(struct camera_device * device,camera_notify_callback notify_cb,camera_data_callback data_cb,camera_data_timestamp_callback data_cb_timestamp,camera_request_memory get_memory,void * user)173 void QCamera2HardwareInterface::set_CallBacks(struct camera_device *device,
174         camera_notify_callback notify_cb,
175         camera_data_callback data_cb,
176         camera_data_timestamp_callback data_cb_timestamp,
177         camera_request_memory get_memory,
178         void *user)
179 {
180     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_SET_CALLBACKS);
181     QCamera2HardwareInterface *hw =
182         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
183     if (!hw) {
184         LOGE("NULL camera device");
185         return;
186     }
187     LOGD("E camera id %d", hw->getCameraId());
188 
189     qcamera_sm_evt_setcb_payload_t payload;
190     payload.notify_cb = notify_cb;
191     payload.data_cb = data_cb;
192     payload.data_cb_timestamp = data_cb_timestamp;
193     payload.get_memory = get_memory;
194     payload.user = user;
195 
196     hw->lockAPI();
197     qcamera_api_result_t apiResult;
198     int32_t rc = hw->processAPI(QCAMERA_SM_EVT_SET_CALLBACKS, (void *)&payload);
199     if (rc == NO_ERROR) {
200         hw->waitAPIResult(QCAMERA_SM_EVT_SET_CALLBACKS, &apiResult);
201     }
202     hw->unlockAPI();
203     LOGD("X camera id %d", hw->getCameraId());
204 
205 }
206 
207 /*===========================================================================
208  * FUNCTION   : enable_msg_type
209  *
210  * DESCRIPTION: enable certain msg type
211  *
212  * PARAMETERS :
213  *   @device     : ptr to camera device struct
214  *   @msg_type   : msg type mask
215  *
216  * RETURN     : none
217  *==========================================================================*/
enable_msg_type(struct camera_device * device,int32_t msg_type)218 void QCamera2HardwareInterface::enable_msg_type(struct camera_device *device, int32_t msg_type)
219 {
220     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_ENABLE_MSG_TYPE);
221     QCamera2HardwareInterface *hw =
222         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
223     if (!hw) {
224         LOGE("NULL camera device");
225         return;
226     }
227     LOGD("E camera id %d", hw->getCameraId());
228 
229     hw->lockAPI();
230     qcamera_api_result_t apiResult;
231     int32_t rc = hw->processAPI(QCAMERA_SM_EVT_ENABLE_MSG_TYPE, (void *)&msg_type);
232     if (rc == NO_ERROR) {
233         hw->waitAPIResult(QCAMERA_SM_EVT_ENABLE_MSG_TYPE, &apiResult);
234     }
235     hw->unlockAPI();
236     LOGD("X camera id %d", hw->getCameraId());
237 
238 }
239 
240 /*===========================================================================
241  * FUNCTION   : disable_msg_type
242  *
243  * DESCRIPTION: disable certain msg type
244  *
245  * PARAMETERS :
246  *   @device     : ptr to camera device struct
247  *   @msg_type   : msg type mask
248  *
249  * RETURN     : none
250  *==========================================================================*/
disable_msg_type(struct camera_device * device,int32_t msg_type)251 void QCamera2HardwareInterface::disable_msg_type(struct camera_device *device, int32_t msg_type)
252 {
253     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_DISABLE_MSG_TYPE);
254     QCamera2HardwareInterface *hw =
255         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
256     if (!hw) {
257         LOGE("NULL camera device");
258         return;
259     }
260     LOGD("E camera id %d", hw->getCameraId());
261 
262     hw->lockAPI();
263     qcamera_api_result_t apiResult;
264     int32_t rc = hw->processAPI(QCAMERA_SM_EVT_DISABLE_MSG_TYPE, (void *)&msg_type);
265     if (rc == NO_ERROR) {
266         hw->waitAPIResult(QCAMERA_SM_EVT_DISABLE_MSG_TYPE, &apiResult);
267     }
268     hw->unlockAPI();
269     LOGD("X camera id %d", hw->getCameraId());
270 
271 }
272 
273 /*===========================================================================
274  * FUNCTION   : msg_type_enabled
275  *
276  * DESCRIPTION: if certain msg type is enabled
277  *
278  * PARAMETERS :
279  *   @device     : ptr to camera device struct
280  *   @msg_type   : msg type mask
281  *
282  * RETURN     : 1 -- enabled
283  *              0 -- not enabled
284  *==========================================================================*/
msg_type_enabled(struct camera_device * device,int32_t msg_type)285 int QCamera2HardwareInterface::msg_type_enabled(struct camera_device *device, int32_t msg_type)
286 {
287     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_MSG_TYPE_ENABLED);
288     int ret = NO_ERROR;
289     QCamera2HardwareInterface *hw =
290         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
291     if (!hw) {
292         LOGE("NULL camera device");
293         return BAD_VALUE;
294     }
295     LOGD("E camera id %d", hw->getCameraId());
296 
297     hw->lockAPI();
298     qcamera_api_result_t apiResult;
299     ret = hw->processAPI(QCAMERA_SM_EVT_MSG_TYPE_ENABLED, (void *)&msg_type);
300     if (ret == NO_ERROR) {
301         hw->waitAPIResult(QCAMERA_SM_EVT_MSG_TYPE_ENABLED, &apiResult);
302         ret = apiResult.enabled;
303     }
304     hw->unlockAPI();
305     LOGD("X camera id %d", hw->getCameraId());
306 
307    return ret;
308 }
309 
310 /*===========================================================================
311  * FUNCTION   : prepare_preview
312  *
313  * DESCRIPTION: prepare preview
314  *
315  * PARAMETERS :
316  *   @device  : ptr to camera device struct
317  *
318  * RETURN     : int32_t type of status
319  *              NO_ERROR  -- success
320  *              none-zero failure code
321  *==========================================================================*/
prepare_preview(struct camera_device * device)322 int QCamera2HardwareInterface::prepare_preview(struct camera_device *device)
323 {
324     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PREPARE_PREVIEW);
325     int ret = NO_ERROR;
326     QCamera2HardwareInterface *hw =
327         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
328     if (!hw) {
329         LOGE("NULL camera device");
330         return BAD_VALUE;
331     }
332     LOGH("[KPI Perf]: E PROFILE_PREPARE_PREVIEW camera id %d",
333              hw->getCameraId());
334     hw->lockAPI();
335     qcamera_api_result_t apiResult;
336     qcamera_sm_evt_enum_t evt = QCAMERA_SM_EVT_PREPARE_PREVIEW;
337     ret = hw->processAPI(evt, NULL);
338     if (ret == NO_ERROR) {
339         hw->waitAPIResult(evt, &apiResult);
340         ret = apiResult.status;
341     }
342     hw->unlockAPI();
343     LOGH("[KPI Perf]: X");
344     return ret;
345 }
346 
347 
348 /*===========================================================================
349  * FUNCTION   : start_preview
350  *
351  * DESCRIPTION: start preview
352  *
353  * PARAMETERS :
354  *   @device  : ptr to camera device struct
355  *
356  * RETURN     : int32_t type of status
357  *              NO_ERROR  -- success
358  *              none-zero failure code
359  *==========================================================================*/
start_preview(struct camera_device * device)360 int QCamera2HardwareInterface::start_preview(struct camera_device *device)
361 {
362     KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_START_PREVIEW);
363     int ret = NO_ERROR;
364     QCamera2HardwareInterface *hw =
365         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
366     if (!hw) {
367         LOGE("NULL camera device");
368         return BAD_VALUE;
369     }
370     LOGI("[KPI Perf]: E PROFILE_START_PREVIEW camera id %d",
371              hw->getCameraId());
372 
373     hw->m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_START_PREVIEW);
374     hw->lockAPI();
375     qcamera_api_result_t apiResult;
376     qcamera_sm_evt_enum_t evt = QCAMERA_SM_EVT_START_PREVIEW;
377     if (hw->isNoDisplayMode()) {
378         evt = QCAMERA_SM_EVT_START_NODISPLAY_PREVIEW;
379     }
380     ret = hw->processAPI(evt, NULL);
381     if (ret == NO_ERROR) {
382         hw->waitAPIResult(evt, &apiResult);
383         ret = apiResult.status;
384     }
385     hw->unlockAPI();
386     hw->m_bPreviewStarted = true;
387     LOGI("[KPI Perf]: X ret = %d", ret);
388     return ret;
389 }
390 
391 /*===========================================================================
392  * FUNCTION   : stop_preview
393  *
394  * DESCRIPTION: stop preview
395  *
396  * PARAMETERS :
397  *   @device  : ptr to camera device struct
398  *
399  * RETURN     : none
400  *==========================================================================*/
stop_preview(struct camera_device * device)401 void QCamera2HardwareInterface::stop_preview(struct camera_device *device)
402 {
403     KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_STOP_PREVIEW);
404     QCamera2HardwareInterface *hw =
405         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
406     if (!hw) {
407         LOGE("NULL camera device");
408         return;
409     }
410     LOGI("[KPI Perf]: E PROFILE_STOP_PREVIEW camera id %d",
411              hw->getCameraId());
412 
413     // Disable power Hint for preview
414     hw->m_perfLockMgr.releasePerfLock(PERF_LOCK_POWERHINT_PREVIEW);
415 
416     hw->m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_STOP_PREVIEW);
417 
418     hw->lockAPI();
419     qcamera_api_result_t apiResult;
420     int32_t ret = hw->processAPI(QCAMERA_SM_EVT_STOP_PREVIEW, NULL);
421     if (ret == NO_ERROR) {
422         hw->waitAPIResult(QCAMERA_SM_EVT_STOP_PREVIEW, &apiResult);
423     }
424     hw->unlockAPI();
425     LOGI("[KPI Perf]: X ret = %d", ret);
426 }
427 
428 /*===========================================================================
429  * FUNCTION   : preview_enabled
430  *
431  * DESCRIPTION: if preview is running
432  *
433  * PARAMETERS :
434  *   @device  : ptr to camera device struct
435  *
436  * RETURN     : 1 -- running
437  *              0 -- not running
438  *==========================================================================*/
preview_enabled(struct camera_device * device)439 int QCamera2HardwareInterface::preview_enabled(struct camera_device *device)
440 {
441     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PREVIEW_ENABLED);
442     int ret = NO_ERROR;
443     QCamera2HardwareInterface *hw =
444         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
445     if (!hw) {
446         LOGE("NULL camera device");
447         return BAD_VALUE;
448     }
449     LOGD("E camera id %d", hw->getCameraId());
450 
451     hw->lockAPI();
452     qcamera_api_result_t apiResult;
453     ret = hw->processAPI(QCAMERA_SM_EVT_PREVIEW_ENABLED, NULL);
454     if (ret == NO_ERROR) {
455         hw->waitAPIResult(QCAMERA_SM_EVT_PREVIEW_ENABLED, &apiResult);
456         ret = apiResult.enabled;
457     }
458 
459     //if preview enabled, can enable preview callback send
460     if(apiResult.enabled) {
461         hw->m_stateMachine.setPreviewCallbackNeeded(true);
462     }
463     hw->unlockAPI();
464     LOGD("X camera id %d", hw->getCameraId());
465 
466     return ret;
467 }
468 
469 /*===========================================================================
470  * FUNCTION   : store_meta_data_in_buffers
471  *
472  * DESCRIPTION: if need to store meta data in buffers for video frame
473  *
474  * PARAMETERS :
475  *   @device  : ptr to camera device struct
476  *   @enable  : flag if enable
477  *
478  * RETURN     : int32_t type of status
479  *              NO_ERROR  -- success
480  *              none-zero failure code
481  *==========================================================================*/
store_meta_data_in_buffers(struct camera_device * device,int enable)482 int QCamera2HardwareInterface::store_meta_data_in_buffers(
483                 struct camera_device *device, int enable)
484 {
485     int ret = NO_ERROR;
486     QCamera2HardwareInterface *hw =
487         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
488     if (!hw) {
489         LOGE("NULL camera device");
490         return BAD_VALUE;
491     }
492     LOGD("E camera id %d", hw->getCameraId());
493 
494     hw->lockAPI();
495     qcamera_api_result_t apiResult;
496     ret = hw->processAPI(QCAMERA_SM_EVT_STORE_METADATA_IN_BUFS, (void *)&enable);
497     if (ret == NO_ERROR) {
498         hw->waitAPIResult(QCAMERA_SM_EVT_STORE_METADATA_IN_BUFS, &apiResult);
499         ret = apiResult.status;
500     }
501     hw->unlockAPI();
502     LOGD("X camera id %d", hw->getCameraId());
503 
504     return ret;
505 }
506 
507 /*===========================================================================
508  * FUNCTION   : restart_start_preview
509  *
510  * DESCRIPTION: start preview as part of the restart preview
511  *
512  * PARAMETERS :
513  *   @device  : ptr to camera device struct
514  *
515  * RETURN     : int32_t type of status
516  *              NO_ERROR  -- success
517  *              none-zero failure code
518  *==========================================================================*/
restart_start_preview(struct camera_device * device)519 int QCamera2HardwareInterface::restart_start_preview(struct camera_device *device)
520 {
521     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_RESTART_START_PREVIEW);
522     int ret = NO_ERROR;
523     QCamera2HardwareInterface *hw =
524         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
525     if (!hw) {
526         LOGE("NULL camera device");
527         return BAD_VALUE;
528     }
529     LOGI("E camera id %d", hw->getCameraId());
530     hw->lockAPI();
531     qcamera_api_result_t apiResult;
532 
533     if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
534         ret = hw->processAPI(QCAMERA_SM_EVT_RESTART_START_PREVIEW, NULL);
535         if (ret == NO_ERROR) {
536             hw->waitAPIResult(QCAMERA_SM_EVT_RESTART_START_PREVIEW, &apiResult);
537             ret = apiResult.status;
538         }
539     } else {
540         LOGE("This function is not supposed to be called in single-camera mode");
541         ret = INVALID_OPERATION;
542     }
543     // Preview restart done, update the mPreviewRestartNeeded flag to false.
544     hw->mPreviewRestartNeeded = false;
545     hw->unlockAPI();
546     LOGI("X camera id %d", hw->getCameraId());
547 
548     return ret;
549 }
550 
551 /*===========================================================================
552  * FUNCTION   : restart_stop_preview
553  *
554  * DESCRIPTION: stop preview as part of the restart preview
555  *
556  * PARAMETERS :
557  *   @device  : ptr to camera device struct
558  *
559  * RETURN     : int32_t type of status
560  *              NO_ERROR  -- success
561  *              none-zero failure code
562  *==========================================================================*/
restart_stop_preview(struct camera_device * device)563 int QCamera2HardwareInterface::restart_stop_preview(struct camera_device *device)
564 {
565     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_RESTART_STOP_PREVIEW);
566     int ret = NO_ERROR;
567     QCamera2HardwareInterface *hw =
568         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
569     if (!hw) {
570         LOGE("NULL camera device");
571         return BAD_VALUE;
572     }
573     LOGI("E camera id %d", hw->getCameraId());
574     hw->lockAPI();
575     qcamera_api_result_t apiResult;
576 
577     if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
578         ret = hw->processAPI(QCAMERA_SM_EVT_RESTART_STOP_PREVIEW, NULL);
579         if (ret == NO_ERROR) {
580             hw->waitAPIResult(QCAMERA_SM_EVT_RESTART_STOP_PREVIEW, &apiResult);
581             ret = apiResult.status;
582         }
583     } else {
584         LOGE("This function is not supposed to be called in single-camera mode");
585         ret = INVALID_OPERATION;
586     }
587 
588     hw->unlockAPI();
589     LOGI("X camera id %d", hw->getCameraId());
590 
591     return ret;
592 }
593 
594 /*===========================================================================
595  * FUNCTION   : pre_start_recording
596  *
597  * DESCRIPTION: prepare for the start recording
598  *
599  * PARAMETERS :
600  *   @device  : ptr to camera device struct
601  *
602  * RETURN     : int32_t type of status
603  *              NO_ERROR  -- success
604  *              none-zero failure code
605  *==========================================================================*/
pre_start_recording(struct camera_device * device)606 int QCamera2HardwareInterface::pre_start_recording(struct camera_device *device)
607 {
608     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PRE_START_RECORDING);
609     int ret = NO_ERROR;
610     QCamera2HardwareInterface *hw =
611         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
612     if (!hw) {
613         LOGE("NULL camera device");
614         return BAD_VALUE;
615     }
616     LOGH("[KPI Perf]: E PROFILE_PRE_START_RECORDING camera id %d",
617           hw->getCameraId());
618     hw->lockAPI();
619     qcamera_api_result_t apiResult;
620     ret = hw->processAPI(QCAMERA_SM_EVT_PRE_START_RECORDING, NULL);
621     if (ret == NO_ERROR) {
622         hw->waitAPIResult(QCAMERA_SM_EVT_PRE_START_RECORDING, &apiResult);
623         ret = apiResult.status;
624     }
625     hw->unlockAPI();
626     LOGH("[KPI Perf]: X");
627     return ret;
628 }
629 
630 /*===========================================================================
631  * FUNCTION   : start_recording
632  *
633  * DESCRIPTION: start recording
634  *
635  * PARAMETERS :
636  *   @device  : ptr to camera device struct
637  *
638  * RETURN     : int32_t type of status
639  *              NO_ERROR  -- success
640  *              none-zero failure code
641  *==========================================================================*/
start_recording(struct camera_device * device)642 int QCamera2HardwareInterface::start_recording(struct camera_device *device)
643 {
644     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_START_RECORDING);
645     int ret = NO_ERROR;
646     QCamera2HardwareInterface *hw =
647         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
648     if (!hw) {
649         LOGE("NULL camera device");
650         return BAD_VALUE;
651     }
652 
653     hw->m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_START_RECORDING);
654 
655     LOGI("[KPI Perf]: E PROFILE_START_RECORDING camera id %d",
656           hw->getCameraId());
657     // Give HWI control to call pre_start_recording in single camera mode.
658     // In dual-cam mode, this control belongs to muxer.
659     if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
660         ret = pre_start_recording(device);
661         if (ret != NO_ERROR) {
662             LOGE("pre_start_recording failed with ret = %d", ret);
663             hw->m_perfLockMgr.releasePerfLock(PERF_LOCK_START_RECORDING);
664             return ret;
665         }
666     }
667 
668     hw->lockAPI();
669     qcamera_api_result_t apiResult;
670     ret = hw->processAPI(QCAMERA_SM_EVT_START_RECORDING, NULL);
671     if (ret == NO_ERROR) {
672         hw->waitAPIResult(QCAMERA_SM_EVT_START_RECORDING, &apiResult);
673         ret = apiResult.status;
674     }
675     hw->unlockAPI();
676     hw->m_bRecordStarted = true;
677     LOGI("[KPI Perf]: X ret = %d", ret);
678 
679     return ret;
680 }
681 
682 /*===========================================================================
683  * FUNCTION   : stop_recording
684  *
685  * DESCRIPTION: stop recording
686  *
687  * PARAMETERS :
688  *   @device  : ptr to camera device struct
689  *
690  * RETURN     : none
691  *==========================================================================*/
stop_recording(struct camera_device * device)692 void QCamera2HardwareInterface::stop_recording(struct camera_device *device)
693 {
694     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_STOP_RECORDING);
695     QCamera2HardwareInterface *hw =
696         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
697     if (!hw) {
698         LOGE("NULL camera device");
699         return;
700     }
701 
702     hw->m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_STOP_RECORDING);
703 
704     LOGI("[KPI Perf]: E PROFILE_STOP_RECORDING camera id %d",
705              hw->getCameraId());
706 
707     hw->lockAPI();
708     qcamera_api_result_t apiResult;
709     int32_t ret = hw->processAPI(QCAMERA_SM_EVT_STOP_RECORDING, NULL);
710     if (ret == NO_ERROR) {
711         hw->waitAPIResult(QCAMERA_SM_EVT_STOP_RECORDING, &apiResult);
712     }
713     hw->unlockAPI();
714     LOGI("[KPI Perf]: X ret = %d", ret);
715 }
716 
717 /*===========================================================================
718  * FUNCTION   : recording_enabled
719  *
720  * DESCRIPTION: if recording is running
721  *
722  * PARAMETERS :
723  *   @device  : ptr to camera device struct
724  *
725  * RETURN     : 1 -- running
726  *              0 -- not running
727  *==========================================================================*/
recording_enabled(struct camera_device * device)728 int QCamera2HardwareInterface::recording_enabled(struct camera_device *device)
729 {
730     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_RECORDING_ENABLED);
731     int ret = NO_ERROR;
732     QCamera2HardwareInterface *hw =
733         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
734     if (!hw) {
735         LOGE("NULL camera device");
736         return BAD_VALUE;
737     }
738     LOGD("E camera id %d", hw->getCameraId());
739     hw->lockAPI();
740     qcamera_api_result_t apiResult;
741     ret = hw->processAPI(QCAMERA_SM_EVT_RECORDING_ENABLED, NULL);
742     if (ret == NO_ERROR) {
743         hw->waitAPIResult(QCAMERA_SM_EVT_RECORDING_ENABLED, &apiResult);
744         ret = apiResult.enabled;
745     }
746     hw->unlockAPI();
747     LOGD("X camera id %d", hw->getCameraId());
748 
749     return ret;
750 }
751 
752 /*===========================================================================
753  * FUNCTION   : release_recording_frame
754  *
755  * DESCRIPTION: return recording frame back
756  *
757  * PARAMETERS :
758  *   @device  : ptr to camera device struct
759  *   @opaque  : ptr to frame to be returned
760  *
761  * RETURN     : none
762  *==========================================================================*/
release_recording_frame(struct camera_device * device,const void * opaque)763 void QCamera2HardwareInterface::release_recording_frame(
764             struct camera_device *device, const void *opaque)
765 {
766     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_REL_REC_FRAME);
767     int32_t ret = NO_ERROR;
768     QCamera2HardwareInterface *hw =
769         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
770     if (!hw) {
771         LOGE("NULL camera device");
772         return;
773     }
774     if (!opaque) {
775         LOGE("Error!! Frame info is NULL");
776         return;
777     }
778     LOGD("E camera id %d", hw->getCameraId());
779 
780     hw->lockAPI();
781     qcamera_api_result_t apiResult;
782     ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, (void *)opaque);
783     if (ret == NO_ERROR) {
784         hw->waitAPIResult(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, &apiResult);
785     }
786     hw->unlockAPI();
787     LOGD("X camera id %d", hw->getCameraId());
788 }
789 
790 /*===========================================================================
791  * FUNCTION   : auto_focus
792  *
793  * DESCRIPTION: start auto focus
794  *
795  * PARAMETERS :
796  *   @device  : ptr to camera device struct
797  *
798  * RETURN     : int32_t type of status
799  *              NO_ERROR  -- success
800  *              none-zero failure code
801  *==========================================================================*/
auto_focus(struct camera_device * device)802 int QCamera2HardwareInterface::auto_focus(struct camera_device *device)
803 {
804     KPI_ATRACE_INT("Camera:AutoFocus", 1);
805     int ret = NO_ERROR;
806     QCamera2HardwareInterface *hw =
807         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
808     if (!hw) {
809         LOGE("NULL camera device");
810         return BAD_VALUE;
811     }
812     LOGH("[KPI Perf] : E PROFILE_AUTO_FOCUS camera id %d",
813              hw->getCameraId());
814     hw->lockAPI();
815     qcamera_api_result_t apiResult;
816     ret = hw->processAPI(QCAMERA_SM_EVT_START_AUTO_FOCUS, NULL);
817     if (ret == NO_ERROR) {
818         hw->waitAPIResult(QCAMERA_SM_EVT_START_AUTO_FOCUS, &apiResult);
819         ret = apiResult.status;
820     }
821     hw->unlockAPI();
822     LOGH("[KPI Perf] : X ret = %d", ret);
823 
824     return ret;
825 }
826 
827 /*===========================================================================
828  * FUNCTION   : cancel_auto_focus
829  *
830  * DESCRIPTION: cancel auto focus
831  *
832  * PARAMETERS :
833  *   @device  : ptr to camera device struct
834  *
835  * RETURN     : int32_t type of status
836  *              NO_ERROR  -- success
837  *              none-zero failure code
838  *==========================================================================*/
cancel_auto_focus(struct camera_device * device)839 int QCamera2HardwareInterface::cancel_auto_focus(struct camera_device *device)
840 {
841     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_CANCEL_AF);
842     int ret = NO_ERROR;
843     QCamera2HardwareInterface *hw =
844         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
845     if (!hw) {
846         LOGE("NULL camera device");
847         return BAD_VALUE;
848     }
849     LOGH("[KPI Perf] : E PROFILE_CANCEL_AUTO_FOCUS camera id %d",
850              hw->getCameraId());
851     hw->lockAPI();
852     qcamera_api_result_t apiResult;
853     ret = hw->processAPI(QCAMERA_SM_EVT_STOP_AUTO_FOCUS, NULL);
854     if (ret == NO_ERROR) {
855         hw->waitAPIResult(QCAMERA_SM_EVT_STOP_AUTO_FOCUS, &apiResult);
856         ret = apiResult.status;
857     }
858     hw->unlockAPI();
859     LOGH("[KPI Perf] : X ret = %d", ret);
860     return ret;
861 }
862 
863 /*===========================================================================
864  * FUNCTION   : pre_take_picture
865  *
866  * DESCRIPTION: pre take picture, restart preview if necessary.
867  *
868  * PARAMETERS :
869  *   @device  : ptr to camera device struct
870  *
871  * RETURN     : int32_t type of status
872  *              NO_ERROR  -- success
873  *              none-zero failure code
874  *==========================================================================*/
pre_take_picture(struct camera_device * device)875 int QCamera2HardwareInterface::pre_take_picture(struct camera_device *device)
876 {
877     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PRE_TAKE_PICTURE);
878     int ret = NO_ERROR;
879     QCamera2HardwareInterface *hw =
880         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
881     if (!hw) {
882         LOGE("NULL camera device");
883         return BAD_VALUE;
884     }
885     LOGH("[KPI Perf]: E PROFILE_PRE_TAKE_PICTURE camera id %d",
886           hw->getCameraId());
887     hw->lockAPI();
888     qcamera_api_result_t apiResult;
889     ret = hw->processAPI(QCAMERA_SM_EVT_PRE_TAKE_PICTURE, NULL);
890     if (ret == NO_ERROR) {
891         hw->waitAPIResult(QCAMERA_SM_EVT_PRE_TAKE_PICTURE, &apiResult);
892         ret = apiResult.status;
893     }
894     hw->unlockAPI();
895     LOGH("[KPI Perf]: X");
896     return ret;
897 }
898 
899 /*===========================================================================
900  * FUNCTION   : take_picture
901  *
902  * DESCRIPTION: take picture
903  *
904  * PARAMETERS :
905  *   @device  : ptr to camera device struct
906  *
907  * RETURN     : int32_t type of status
908  *              NO_ERROR  -- success
909  *              none-zero failure code
910  *==========================================================================*/
take_picture(struct camera_device * device)911 int QCamera2HardwareInterface::take_picture(struct camera_device *device)
912 {
913     KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_TAKE_PICTURE);
914     int ret = NO_ERROR;
915     QCamera2HardwareInterface *hw =
916         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
917     if (!hw) {
918         LOGE("NULL camera device");
919         return BAD_VALUE;
920     }
921     LOGI("[KPI Perf]: E PROFILE_TAKE_PICTURE camera id %d",
922              hw->getCameraId());
923 
924     // Acquire the perf lock for JPEG snapshot only
925     if (hw->mParameters.isJpegPictureFormat()) {
926         hw->m_perfLockMgr.acquirePerfLock(PERF_LOCK_TAKE_SNAPSHOT);
927     }
928 
929     qcamera_api_result_t apiResult;
930 
931    /** Added support for Retro-active Frames:
932      *  takePicture() is called before preparing Snapshot to indicate the
933      *  mm-camera-channel to pick up legacy frames even
934      *  before LED estimation is triggered.
935      */
936 
937     LOGH("isLiveSnap %d, isZSL %d, isHDR %d longshot = %d",
938            hw->isLiveSnapshot(), hw->isZSLMode(), hw->isHDRMode(),
939            hw->isLongshotEnabled());
940 
941     // Check for Retro-active Frames
942     if ((hw->mParameters.getNumOfRetroSnapshots() > 0) &&
943         !hw->isLiveSnapshot() && hw->isZSLMode() &&
944         !hw->isHDRMode() && !hw->isLongshotEnabled()) {
945         // Set Retro Picture Mode
946         hw->setRetroPicture(1);
947         hw->m_bLedAfAecLock = 0;
948         LOGL("Retro Enabled");
949 
950         // Give HWI control to call pre_take_picture in single camera mode.
951         // In dual-cam mode, this control belongs to muxer.
952         if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
953             ret = pre_take_picture(device);
954             if (ret != NO_ERROR) {
955                 LOGE("pre_take_picture failed with ret = %d",ret);
956                 return ret;
957             }
958         }
959 
960         /* Call take Picture for total number of snapshots required.
961              This includes the number of retro frames and normal frames */
962         hw->lockAPI();
963         ret = hw->processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL);
964         if (ret == NO_ERROR) {
965           // Wait for retro frames, before calling prepare snapshot
966           LOGD("Wait for Retro frames to be done");
967           hw->waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult);
968             ret = apiResult.status;
969         }
970         /* Unlock API since it is acquired in prepare snapshot seperately */
971         hw->unlockAPI();
972 
973         /* Prepare snapshot in case LED needs to be flashed */
974         LOGD("Start Prepare Snapshot");
975         ret = hw->prepare_snapshot(device);
976     }
977     else {
978         hw->setRetroPicture(0);
979         // Check if prepare snapshot is done
980         if (!hw->mPrepSnapRun) {
981             // Ignore the status from prepare_snapshot
982             hw->prepare_snapshot(device);
983         }
984 
985         // Give HWI control to call pre_take_picture in single camera mode.
986         // In dual-cam mode, this control belongs to muxer.
987         if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
988             ret = pre_take_picture(device);
989             if (ret != NO_ERROR) {
990                 LOGE("pre_take_picture failed with ret = %d",ret);
991                 return ret;
992             }
993         }
994 
995         // Regardless what the result value for prepare_snapshot,
996         // go ahead with capture anyway. Just like the way autofocus
997         // is handled in capture case
998         /* capture */
999         LOGL("Capturing normal frames");
1000         hw->lockAPI();
1001         ret = hw->processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL);
1002         if (ret == NO_ERROR) {
1003           hw->waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult);
1004             ret = apiResult.status;
1005         }
1006         hw->unlockAPI();
1007         if (!hw->isLongshotEnabled()){
1008             // For longshot mode, we prepare snapshot only once
1009             hw->mPrepSnapRun = false;
1010          }
1011     }
1012     LOGI("[KPI Perf]: X ret = %d", ret);
1013     return ret;
1014 }
1015 
1016 /*===========================================================================
1017  * FUNCTION   : cancel_picture
1018  *
1019  * DESCRIPTION: cancel current take picture request
1020  *
1021  * PARAMETERS :
1022  *   @device  : ptr to camera device struct
1023  *
1024  * RETURN     : int32_t type of status
1025  *              NO_ERROR  -- success
1026  *              none-zero failure code
1027  *==========================================================================*/
cancel_picture(struct camera_device * device)1028 int QCamera2HardwareInterface::cancel_picture(struct camera_device *device)
1029 {
1030     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_CANCEL_PICTURE);
1031     int ret = NO_ERROR;
1032     QCamera2HardwareInterface *hw =
1033         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1034     if (!hw) {
1035         LOGE("NULL camera device");
1036         return BAD_VALUE;
1037     }
1038     LOGI("[KPI Perf]: E PROFILE_CANCEL_PICTURE camera id %d",
1039              hw->getCameraId());
1040     hw->lockAPI();
1041     qcamera_api_result_t apiResult;
1042     ret = hw->processAPI(QCAMERA_SM_EVT_CANCEL_PICTURE, NULL);
1043     if (ret == NO_ERROR) {
1044         hw->waitAPIResult(QCAMERA_SM_EVT_CANCEL_PICTURE, &apiResult);
1045         ret = apiResult.status;
1046     }
1047     hw->unlockAPI();
1048     LOGI("[KPI Perf]: X camera id %d ret = %d", hw->getCameraId(), ret);
1049 
1050     return ret;
1051 }
1052 
1053 /*===========================================================================
1054  * FUNCTION   : set_parameters
1055  *
1056  * DESCRIPTION: set camera parameters
1057  *
1058  * PARAMETERS :
1059  *   @device  : ptr to camera device struct
1060  *   @parms   : string of packed parameters
1061  *
1062  * RETURN     : int32_t type of status
1063  *              NO_ERROR  -- success
1064  *              none-zero failure code
1065  *==========================================================================*/
set_parameters(struct camera_device * device,const char * parms)1066 int QCamera2HardwareInterface::set_parameters(struct camera_device *device,
1067                                               const char *parms)
1068 {
1069     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_SET_PARAMETERS);
1070     int ret = NO_ERROR;
1071     QCamera2HardwareInterface *hw =
1072         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1073     if (!hw) {
1074         LOGE("NULL camera device");
1075         return BAD_VALUE;
1076     }
1077     LOGD("E camera id %d", hw->getCameraId());
1078     hw->lockAPI();
1079     qcamera_api_result_t apiResult;
1080     ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS, (void *)parms);
1081     if (ret == NO_ERROR) {
1082         hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS, &apiResult);
1083         ret = apiResult.status;
1084     }
1085 
1086     // Give HWI control to restart (if necessary) after set params
1087     // in single camera mode. In dual-cam mode, this control belongs to muxer.
1088     if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
1089         if ((ret == NO_ERROR) && hw->getNeedRestart()) {
1090             LOGD("stopping after param change");
1091             ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_STOP, NULL);
1092             if (ret == NO_ERROR) {
1093                 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_STOP, &apiResult);
1094                 ret = apiResult.status;
1095             }
1096         }
1097 
1098         if (ret == NO_ERROR) {
1099             LOGD("committing param change");
1100             ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, NULL);
1101             if (ret == NO_ERROR) {
1102                 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, &apiResult);
1103                 ret = apiResult.status;
1104             }
1105         }
1106 
1107         if ((ret == NO_ERROR) && hw->getNeedRestart()) {
1108             LOGD("restarting after param change");
1109             ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_RESTART, NULL);
1110             if (ret == NO_ERROR) {
1111                 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_RESTART, &apiResult);
1112                 ret = apiResult.status;
1113             }
1114         }
1115     }
1116 
1117     hw->unlockAPI();
1118     LOGD("X camera id %d ret %d", hw->getCameraId(), ret);
1119 
1120     return ret;
1121 }
1122 
1123 /*===========================================================================
1124  * FUNCTION   : stop_after_set_params
1125  *
1126  * DESCRIPTION: stop after a set param call, if necessary
1127  *
1128  * PARAMETERS :
1129  *   @device  : ptr to camera device struct
1130  *
1131  * RETURN     : int32_t type of status
1132  *              NO_ERROR  -- success
1133  *              none-zero failure code
1134  *==========================================================================*/
stop_after_set_params(struct camera_device * device)1135 int QCamera2HardwareInterface::stop_after_set_params(struct camera_device *device)
1136 {
1137     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_STOP_AFTER_SET_PARAMS);
1138     int ret = NO_ERROR;
1139     QCamera2HardwareInterface *hw =
1140         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1141     if (!hw) {
1142         LOGE("NULL camera device");
1143         return BAD_VALUE;
1144     }
1145     LOGD("E camera id %d", hw->getCameraId());
1146     hw->lockAPI();
1147     qcamera_api_result_t apiResult;
1148 
1149     if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
1150         ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_STOP, NULL);
1151         if (ret == NO_ERROR) {
1152             hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_STOP, &apiResult);
1153             ret = apiResult.status;
1154         }
1155     } else {
1156         LOGE("is not supposed to be called in single-camera mode");
1157         ret = INVALID_OPERATION;
1158     }
1159 
1160     hw->unlockAPI();
1161     LOGD("X camera id %d", hw->getCameraId());
1162 
1163     return ret;
1164 }
1165 
1166 /*===========================================================================
1167  * FUNCTION   : commit_params
1168  *
1169  * DESCRIPTION: commit after a set param call
1170  *
1171  * PARAMETERS :
1172  *   @device  : ptr to camera device struct
1173  *
1174  * RETURN     : int32_t type of status
1175  *              NO_ERROR  -- success
1176  *              none-zero failure code
1177  *==========================================================================*/
commit_params(struct camera_device * device)1178 int QCamera2HardwareInterface::commit_params(struct camera_device *device)
1179 {
1180     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_COMMIT_PARAMS);
1181     int ret = NO_ERROR;
1182     QCamera2HardwareInterface *hw =
1183         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1184     if (!hw) {
1185         LOGE("NULL camera device");
1186         return BAD_VALUE;
1187     }
1188     LOGD("E camera id %d", hw->getCameraId());
1189     hw->lockAPI();
1190     qcamera_api_result_t apiResult;
1191 
1192     if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
1193         ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, NULL);
1194         if (ret == NO_ERROR) {
1195             hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, &apiResult);
1196             ret = apiResult.status;
1197         }
1198     } else {
1199         LOGE("is not supposed to be called in single-camera mode");
1200         ret = INVALID_OPERATION;
1201     }
1202 
1203     hw->unlockAPI();
1204     LOGD("X camera id %d", hw->getCameraId());
1205 
1206     return ret;
1207 }
1208 
1209 /*===========================================================================
1210  * FUNCTION   : restart_after_set_params
1211  *
1212  * DESCRIPTION: restart after a set param call, if necessary
1213  *
1214  * PARAMETERS :
1215  *   @device  : ptr to camera device struct
1216  *
1217  * RETURN     : int32_t type of status
1218  *              NO_ERROR  -- success
1219  *              none-zero failure code
1220  *==========================================================================*/
restart_after_set_params(struct camera_device * device)1221 int QCamera2HardwareInterface::restart_after_set_params(struct camera_device *device)
1222 {
1223     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_RESTART_AFTER_SET_PARAMS);
1224     int ret = NO_ERROR;
1225     QCamera2HardwareInterface *hw =
1226         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1227     if (!hw) {
1228         LOGE("NULL camera device");
1229         return BAD_VALUE;
1230     }
1231     LOGD("E camera id %d", hw->getCameraId());
1232     hw->lockAPI();
1233     qcamera_api_result_t apiResult;
1234 
1235     if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
1236         ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_RESTART, NULL);
1237         if (ret == NO_ERROR) {
1238             hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_RESTART, &apiResult);
1239             ret = apiResult.status;
1240         }
1241     } else {
1242         LOGE("is not supposed to be called in single-camera mode");
1243         ret = INVALID_OPERATION;
1244     }
1245 
1246     hw->unlockAPI();
1247     LOGD("X camera id %d", hw->getCameraId());
1248     return ret;
1249 }
1250 
1251 /*===========================================================================
1252  * FUNCTION   : get_parameters
1253  *
1254  * DESCRIPTION: query camera parameters
1255  *
1256  * PARAMETERS :
1257  *   @device  : ptr to camera device struct
1258  *
1259  * RETURN     : packed parameters in a string
1260  *==========================================================================*/
get_parameters(struct camera_device * device)1261 char* QCamera2HardwareInterface::get_parameters(struct camera_device *device)
1262 {
1263     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_GET_PARAMETERS);
1264     char *ret = NULL;
1265     QCamera2HardwareInterface *hw =
1266         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1267     if (!hw) {
1268         LOGE("NULL camera device");
1269         return NULL;
1270     }
1271     LOGD("E camera id %d", hw->getCameraId());
1272     hw->lockAPI();
1273     qcamera_api_result_t apiResult;
1274     int32_t rc = hw->processAPI(QCAMERA_SM_EVT_GET_PARAMS, NULL);
1275     if (rc == NO_ERROR) {
1276         hw->waitAPIResult(QCAMERA_SM_EVT_GET_PARAMS, &apiResult);
1277         ret = apiResult.params;
1278     }
1279     hw->unlockAPI();
1280     LOGD("E camera id %d", hw->getCameraId());
1281 
1282     return ret;
1283 }
1284 
1285 /*===========================================================================
1286  * FUNCTION   : put_parameters
1287  *
1288  * DESCRIPTION: return camera parameters string back to HAL
1289  *
1290  * PARAMETERS :
1291  *   @device  : ptr to camera device struct
1292  *   @parm    : ptr to parameter string to be returned
1293  *
1294  * RETURN     : none
1295  *==========================================================================*/
put_parameters(struct camera_device * device,char * parm)1296 void QCamera2HardwareInterface::put_parameters(struct camera_device *device,
1297                                                char *parm)
1298 {
1299     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PUT_PARAMETERS);
1300     QCamera2HardwareInterface *hw =
1301         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1302     if (!hw) {
1303         LOGE("NULL camera device");
1304         return;
1305     }
1306     LOGD("E camera id %d", hw->getCameraId());
1307     hw->lockAPI();
1308     qcamera_api_result_t apiResult;
1309     int32_t ret = hw->processAPI(QCAMERA_SM_EVT_PUT_PARAMS, (void *)parm);
1310     if (ret == NO_ERROR) {
1311         hw->waitAPIResult(QCAMERA_SM_EVT_PUT_PARAMS, &apiResult);
1312     }
1313     hw->unlockAPI();
1314     LOGD("E camera id %d", hw->getCameraId());
1315 }
1316 
1317 /*===========================================================================
1318  * FUNCTION   : send_command
1319  *
1320  * DESCRIPTION: command to be executed
1321  *
1322  * PARAMETERS :
1323  *   @device  : ptr to camera device struct
1324  *   @cmd     : cmd to be executed
1325  *   @arg1    : ptr to optional argument1
1326  *   @arg2    : ptr to optional argument2
1327  *
1328  * RETURN     : int32_t type of status
1329  *              NO_ERROR  -- success
1330  *              none-zero failure code
1331  *==========================================================================*/
send_command(struct camera_device * device,int32_t cmd,int32_t arg1,int32_t arg2)1332 int QCamera2HardwareInterface::send_command(struct camera_device *device,
1333                                             int32_t cmd,
1334                                             int32_t arg1,
1335                                             int32_t arg2)
1336 {
1337     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_SEND_COMMAND);
1338     int ret = NO_ERROR;
1339     QCamera2HardwareInterface *hw =
1340         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1341     if (!hw) {
1342         LOGE("NULL camera device");
1343         return BAD_VALUE;
1344     }
1345     LOGD("E camera id %d", hw->getCameraId());
1346 
1347     qcamera_sm_evt_command_payload_t payload;
1348     memset(&payload, 0, sizeof(qcamera_sm_evt_command_payload_t));
1349     payload.cmd = cmd;
1350     payload.arg1 = arg1;
1351     payload.arg2 = arg2;
1352     hw->lockAPI();
1353     qcamera_api_result_t apiResult;
1354     ret = hw->processAPI(QCAMERA_SM_EVT_SEND_COMMAND, (void *)&payload);
1355     if (ret == NO_ERROR) {
1356         hw->waitAPIResult(QCAMERA_SM_EVT_SEND_COMMAND, &apiResult);
1357         ret = apiResult.status;
1358     }
1359     hw->unlockAPI();
1360     LOGD("E camera id %d", hw->getCameraId());
1361 
1362     return ret;
1363 }
1364 
1365 /*===========================================================================
1366  * FUNCTION   : send_command_restart
1367  *
1368  * DESCRIPTION: restart if necessary after a send_command
1369  *
1370  * PARAMETERS :
1371  *   @device  : ptr to camera device struct
1372  *   @cmd     : cmd to be executed
1373  *   @arg1    : ptr to optional argument1
1374  *   @arg2    : ptr to optional argument2
1375  *
1376  * RETURN     : int32_t type of status
1377  *              NO_ERROR  -- success
1378  *              none-zero failure code
1379  *==========================================================================*/
send_command_restart(struct camera_device * device,int32_t cmd,int32_t arg1,int32_t arg2)1380 int QCamera2HardwareInterface::send_command_restart(struct camera_device *device,
1381         int32_t cmd,
1382         int32_t arg1,
1383         int32_t arg2)
1384 {
1385     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_SEND_COMMAND_RESTART);
1386     int ret = NO_ERROR;
1387     QCamera2HardwareInterface *hw =
1388             reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1389     if (!hw) {
1390         LOGE("NULL camera device");
1391         return BAD_VALUE;
1392     }
1393 
1394     qcamera_sm_evt_command_payload_t payload;
1395     memset(&payload, 0, sizeof(qcamera_sm_evt_command_payload_t));
1396     payload.cmd = cmd;
1397     payload.arg1 = arg1;
1398     payload.arg2 = arg2;
1399     hw->lockAPI();
1400     qcamera_api_result_t apiResult;
1401     ret = hw->processAPI(QCAMERA_SM_EVT_SEND_COMMAND_RESTART, (void *)&payload);
1402     if (ret == NO_ERROR) {
1403         hw->waitAPIResult(QCAMERA_SM_EVT_SEND_COMMAND_RESTART, &apiResult);
1404         ret = apiResult.status;
1405     }
1406     hw->unlockAPI();
1407     LOGD("E camera id %d", hw->getCameraId());
1408 
1409     return ret;
1410 }
1411 
1412 /*===========================================================================
1413  * FUNCTION   : release
1414  *
1415  * DESCRIPTION: release camera resource
1416  *
1417  * PARAMETERS :
1418  *   @device  : ptr to camera device struct
1419  *
1420  * RETURN     : none
1421  *==========================================================================*/
release(struct camera_device * device)1422 void QCamera2HardwareInterface::release(struct camera_device *device)
1423 {
1424     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_RELEASE);
1425     QCamera2HardwareInterface *hw =
1426         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1427     if (!hw) {
1428         LOGE("NULL camera device");
1429         return;
1430     }
1431     LOGD("E camera id %d", hw->getCameraId());
1432     hw->lockAPI();
1433     qcamera_api_result_t apiResult;
1434     int32_t ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE, NULL);
1435     if (ret == NO_ERROR) {
1436         hw->waitAPIResult(QCAMERA_SM_EVT_RELEASE, &apiResult);
1437     }
1438     hw->unlockAPI();
1439     LOGD("E camera id %d", hw->getCameraId());
1440 }
1441 
1442 /*===========================================================================
1443  * FUNCTION   : dump
1444  *
1445  * DESCRIPTION: dump camera status
1446  *
1447  * PARAMETERS :
1448  *   @device  : ptr to camera device struct
1449  *   @fd      : fd for status to be dumped to
1450  *
1451  * RETURN     : int32_t type of status
1452  *              NO_ERROR  -- success
1453  *              none-zero failure code
1454  *==========================================================================*/
dump(struct camera_device * device,int fd)1455 int QCamera2HardwareInterface::dump(struct camera_device *device, int fd)
1456 {
1457     int ret = NO_ERROR;
1458 
1459     //Log level property is read when "adb shell dumpsys media.camera" is
1460     //called so that the log level can be controlled without restarting
1461     //media server
1462     getLogLevel();
1463     QCamera2HardwareInterface *hw =
1464         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1465     if (!hw) {
1466         LOGE("NULL camera device");
1467         return BAD_VALUE;
1468     }
1469     LOGD("E camera id %d", hw->getCameraId());
1470     hw->lockAPI();
1471     qcamera_api_result_t apiResult;
1472     ret = hw->processAPI(QCAMERA_SM_EVT_DUMP, (void *)&fd);
1473     if (ret == NO_ERROR) {
1474         hw->waitAPIResult(QCAMERA_SM_EVT_DUMP, &apiResult);
1475         ret = apiResult.status;
1476     }
1477     hw->unlockAPI();
1478     LOGD("E camera id %d", hw->getCameraId());
1479 
1480     return ret;
1481 }
1482 
1483 /*===========================================================================
1484  * FUNCTION   : close_camera_device
1485  *
1486  * DESCRIPTION: close camera device
1487  *
1488  * PARAMETERS :
1489  *   @device  : ptr to camera device struct
1490  *
1491  * RETURN     : int32_t type of status
1492  *              NO_ERROR  -- success
1493  *              none-zero failure code
1494  *==========================================================================*/
close_camera_device(hw_device_t * hw_dev)1495 int QCamera2HardwareInterface::close_camera_device(hw_device_t *hw_dev)
1496 {
1497     KPI_ATRACE_CAMSCOPE_BEGIN(CAMSCOPE_HAL1_CLOSECAMERA);
1498     int ret = NO_ERROR;
1499 
1500     QCamera2HardwareInterface *hw =
1501         reinterpret_cast<QCamera2HardwareInterface *>(
1502             reinterpret_cast<camera_device_t *>(hw_dev)->priv);
1503     if (!hw) {
1504         LOGE("NULL camera device");
1505         return BAD_VALUE;
1506     }
1507     LOGI("[KPI Perf]: E camera id %d", hw->getCameraId());
1508     delete hw;
1509     LOGI("[KPI Perf]: X");
1510     KPI_ATRACE_CAMSCOPE_END(CAMSCOPE_HAL1_CLOSECAMERA);
1511     CAMSCOPE_DESTROY(CAMSCOPE_SECTION_HAL);
1512     return ret;
1513 }
1514 
1515 /*===========================================================================
1516  * FUNCTION   : register_face_image
1517  *
1518  * DESCRIPTION: register a face image into imaging lib for face authenticatio/
1519  *              face recognition
1520  *
1521  * PARAMETERS :
1522  *   @device  : ptr to camera device struct
1523  *   @img_ptr : ptr to image buffer
1524  *   @config  : ptr to config about input image, i.e., format, dimension, and etc.
1525  *
1526  * RETURN     : >=0 unique ID of face registerd.
1527  *              <0  failure.
1528  *==========================================================================*/
register_face_image(struct camera_device * device,void * img_ptr,cam_pp_offline_src_config_t * config)1529 int QCamera2HardwareInterface::register_face_image(struct camera_device *device,
1530                                                    void *img_ptr,
1531                                                    cam_pp_offline_src_config_t *config)
1532 {
1533     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_REGISTER_FACE_IMAGE);
1534     int ret = NO_ERROR;
1535     QCamera2HardwareInterface *hw =
1536         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1537     if (!hw) {
1538         LOGE("NULL camera device");
1539         return BAD_VALUE;
1540     }
1541     LOGD("E camera id %d", hw->getCameraId());
1542     qcamera_sm_evt_reg_face_payload_t payload;
1543     memset(&payload, 0, sizeof(qcamera_sm_evt_reg_face_payload_t));
1544     payload.img_ptr = img_ptr;
1545     payload.config = config;
1546     hw->lockAPI();
1547     qcamera_api_result_t apiResult;
1548     ret = hw->processAPI(QCAMERA_SM_EVT_REG_FACE_IMAGE, (void *)&payload);
1549     if (ret == NO_ERROR) {
1550         hw->waitAPIResult(QCAMERA_SM_EVT_REG_FACE_IMAGE, &apiResult);
1551         ret = apiResult.handle;
1552     }
1553     hw->unlockAPI();
1554     LOGD("E camera id %d", hw->getCameraId());
1555 
1556     return ret;
1557 }
1558 
1559 /*===========================================================================
1560  * FUNCTION   : prepare_snapshot
1561  *
1562  * DESCRIPTION: prepares hardware for snapshot
1563  *
1564  * PARAMETERS :
1565  *   @device  : ptr to camera device struct
1566  *
1567  * RETURN     : int32_t type of status
1568  *              NO_ERROR  -- success
1569  *              none-zero failure code
1570  *==========================================================================*/
prepare_snapshot(struct camera_device * device)1571 int QCamera2HardwareInterface::prepare_snapshot(struct camera_device *device)
1572 {
1573     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PREPARE_SNAPSHOT);
1574     int ret = NO_ERROR;
1575     QCamera2HardwareInterface *hw =
1576         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1577     if (!hw) {
1578         LOGE("NULL camera device");
1579         return BAD_VALUE;
1580     }
1581     if (hw->isLongshotEnabled() && hw->mPrepSnapRun == true) {
1582         // For longshot mode, we prepare snapshot only once
1583         LOGH("prepare snapshot only once ");
1584         return NO_ERROR;
1585     }
1586     LOGH("[KPI Perf]: E PROFILE_PREPARE_SNAPSHOT camera id %d",
1587              hw->getCameraId());
1588     hw->lockAPI();
1589     qcamera_api_result_t apiResult;
1590 
1591     /* Prepare snapshot in case LED needs to be flashed */
1592     if (hw->mFlashNeeded || hw->mParameters.isChromaFlashEnabled()) {
1593         /* Prepare snapshot in case LED needs to be flashed */
1594         ret = hw->processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL);
1595         if (ret == NO_ERROR) {
1596           hw->waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, &apiResult);
1597             ret = apiResult.status;
1598         }
1599         hw->mPrepSnapRun = true;
1600     }
1601     hw->unlockAPI();
1602     LOGH("[KPI Perf]: X, ret: %d", ret);
1603     return ret;
1604 }
1605 
1606 /*===========================================================================
1607  * FUNCTION   : QCamera2HardwareInterface
1608  *
1609  * DESCRIPTION: constructor of QCamera2HardwareInterface
1610  *
1611  * PARAMETERS :
1612  *   @cameraId  : camera ID
1613  *
1614  * RETURN     : none
1615  *==========================================================================*/
QCamera2HardwareInterface(uint32_t cameraId)1616 QCamera2HardwareInterface::QCamera2HardwareInterface(uint32_t cameraId)
1617     : mCameraId(cameraId),
1618       mCameraHandle(NULL),
1619       mMasterCamera(CAM_TYPE_MAIN),
1620       mCameraOpened(false),
1621       mDualCamera(false),
1622       m_pFovControl(NULL),
1623       m_bRelCamCalibValid(false),
1624       mPreviewWindow(NULL),
1625       mMsgEnabled(0),
1626       mStoreMetaDataInFrame(0),
1627       mJpegCb(NULL),
1628       mCallbackCookie(NULL),
1629       mJpegCallbackCookie(NULL),
1630       m_bMpoEnabled(TRUE),
1631       m_stateMachine(this),
1632       m_smThreadActive(true),
1633       m_postprocessor(this),
1634       m_thermalAdapter(QCameraThermalAdapter::getInstance()),
1635       m_cbNotifier(this),
1636       m_perfLockMgr(),
1637       m_bPreviewStarted(false),
1638       m_bRecordStarted(false),
1639       m_currentFocusState(CAM_AF_STATE_INACTIVE),
1640       mDumpFrmCnt(0U),
1641       mDumpSkipCnt(0U),
1642       mThermalLevel(QCAMERA_THERMAL_NO_ADJUSTMENT),
1643       mActiveAF(false),
1644       m_HDRSceneEnabled(false),
1645       mLongshotEnabled(false),
1646       mLiveSnapshotThread(0),
1647       mIntPicThread(0),
1648       mFlashNeeded(false),
1649       mFlashConfigured(false),
1650       mDeviceRotation(0U),
1651       mCaptureRotation(0U),
1652       mJpegExifRotation(0U),
1653       mUseJpegExifRotation(false),
1654       mIs3ALocked(false),
1655       mPrepSnapRun(false),
1656       mZoomLevel(0),
1657       mPreviewRestartNeeded(false),
1658       mVFrameCount(0),
1659       mVLastFrameCount(0),
1660       mVLastFpsTime(0),
1661       mVFps(0),
1662       mPFrameCount(0),
1663       mPLastFrameCount(0),
1664       mPLastFpsTime(0),
1665       mPFps(0),
1666       mLowLightConfigured(false),
1667       mInstantAecFrameCount(0),
1668       m_bIntJpegEvtPending(false),
1669       m_bIntRawEvtPending(false),
1670       mReprocJob(0),
1671       mJpegJob(0),
1672       mMetadataAllocJob(0),
1673       mInitPProcJob(0),
1674       mParamAllocJob(0),
1675       mParamInitJob(0),
1676       mOutputCount(0),
1677       mInputCount(0),
1678       mAdvancedCaptureConfigured(false),
1679       mHDRBracketingEnabled(false),
1680       mNumPreviewFaces(-1),
1681       mJpegClientHandle(0),
1682       mJpegHandleOwner(false),
1683       mMetadataMem(NULL),
1684       mCACDoneReceived(false),
1685       m_bNeedRestart(false),
1686       mBootToMonoTimestampOffset(0),
1687       bDepthAFCallbacks(true),
1688       m_bNeedHalPP(FALSE)
1689 {
1690 #ifdef TARGET_TS_MAKEUP
1691     memset(&mFaceRect, -1, sizeof(mFaceRect));
1692 #endif
1693     getLogLevel();
1694     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_QCAMERA2HWI);
1695     mCameraDevice.common.tag = HARDWARE_DEVICE_TAG;
1696     mCameraDevice.common.version = HARDWARE_DEVICE_API_VERSION(1, 0);
1697     mCameraDevice.common.close = close_camera_device;
1698     mCameraDevice.ops = &mCameraOps;
1699     mCameraDevice.priv = this;
1700 
1701     mDualCamera = is_dual_camera_by_idx(cameraId);
1702 
1703     pthread_mutex_init(&m_lock, NULL);
1704     pthread_cond_init(&m_cond, NULL);
1705 
1706     m_apiResultList = NULL;
1707 
1708     pthread_mutex_init(&m_evtLock, NULL);
1709     pthread_cond_init(&m_evtCond, NULL);
1710     memset(&m_evtResult, 0, sizeof(qcamera_api_result_t));
1711 
1712 
1713     pthread_mutex_init(&m_int_lock, NULL);
1714     pthread_cond_init(&m_int_cond, NULL);
1715 
1716     memset(m_channels, 0, sizeof(m_channels));
1717 
1718     memset(&mExifParams, 0, sizeof(mm_jpeg_exif_params_t));
1719 
1720     memset(m_BackendFileName, 0, QCAMERA_MAX_FILEPATH_LENGTH);
1721 
1722     memset(mDefOngoingJobs, 0, sizeof(mDefOngoingJobs));
1723     memset(&mJpegMetadata, 0, sizeof(mJpegMetadata));
1724     memset(&mJpegHandle, 0, sizeof(mJpegHandle));
1725     memset(&mJpegMpoHandle, 0, sizeof(mJpegMpoHandle));
1726 
1727     mDeferredWorkThread.launch(deferredWorkRoutine, this);
1728     mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_START_DATA_PROC, FALSE, FALSE);
1729 
1730     pthread_mutex_init(&mGrallocLock, NULL);
1731     mEnqueuedBuffers = 0;
1732     mFrameSkipStart = 0;
1733     mFrameSkipEnd = 0;
1734     mLastPreviewFrameID = 0;
1735 
1736     //Load and read GPU library.
1737     lib_surface_utils = NULL;
1738     LINK_get_surface_pixel_alignment = NULL;
1739     mSurfaceStridePadding = CAM_PAD_TO_32;
1740     lib_surface_utils = dlopen("libadreno_utils.so", RTLD_NOW);
1741     if (lib_surface_utils) {
1742         *(void **)&LINK_get_surface_pixel_alignment =
1743                 dlsym(lib_surface_utils, "get_gpu_pixel_alignment");
1744          if (LINK_get_surface_pixel_alignment) {
1745              mSurfaceStridePadding = LINK_get_surface_pixel_alignment();
1746          }
1747          dlclose(lib_surface_utils);
1748     }
1749 }
1750 
1751 /*===========================================================================
1752  * FUNCTION   : ~QCamera2HardwareInterface
1753  *
1754  * DESCRIPTION: destructor of QCamera2HardwareInterface
1755  *
1756  * PARAMETERS : none
1757  *
1758  * RETURN     : none
1759  *==========================================================================*/
~QCamera2HardwareInterface()1760 QCamera2HardwareInterface::~QCamera2HardwareInterface()
1761 {
1762     LOGH("E");
1763 
1764     mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_STOP_DATA_PROC, TRUE, TRUE);
1765     mDeferredWorkThread.exit();
1766 
1767     if (mMetadataMem != NULL) {
1768         delete mMetadataMem;
1769         mMetadataMem = NULL;
1770     }
1771 
1772     if (m_pFovControl) {
1773         delete m_pFovControl;
1774         m_pFovControl = NULL;
1775     }
1776 
1777     m_perfLockMgr.acquirePerfLock(PERF_LOCK_CLOSE_CAMERA);
1778     lockAPI();
1779     m_smThreadActive = false;
1780     unlockAPI();
1781     m_stateMachine.releaseThread();
1782     closeCamera();
1783     m_perfLockMgr.releasePerfLock(PERF_LOCK_CLOSE_CAMERA);
1784 
1785     pthread_mutex_destroy(&m_lock);
1786     pthread_cond_destroy(&m_cond);
1787     pthread_mutex_destroy(&m_evtLock);
1788     pthread_cond_destroy(&m_evtCond);
1789     pthread_mutex_destroy(&m_int_lock);
1790     pthread_cond_destroy(&m_int_cond);
1791     pthread_mutex_destroy(&mGrallocLock);
1792     LOGH("X");
1793 }
1794 
1795 /*===========================================================================
1796  * FUNCTION   : deferPPInit
1797  *
1798  * DESCRIPTION: Queue postproc init task to deferred thread
1799  *
1800  * PARAMETERS : none
1801  *
1802  * RETURN     : uint32_t job id of pproc init job
1803  *              0  -- failure
1804  *==========================================================================*/
deferPPInit()1805 uint32_t QCamera2HardwareInterface::deferPPInit()
1806 {
1807     // init pproc
1808     DeferWorkArgs args;
1809     DeferPProcInitArgs pprocInitArgs;
1810 
1811     memset(&args, 0, sizeof(DeferWorkArgs));
1812     memset(&pprocInitArgs, 0, sizeof(DeferPProcInitArgs));
1813 
1814     pprocInitArgs.jpeg_cb = jpegEvtHandle;
1815     pprocInitArgs.user_data = this;
1816     args.pprocInitArgs = pprocInitArgs;
1817 
1818     return queueDeferredWork(CMD_DEF_PPROC_INIT,
1819             args);
1820 }
1821 
1822 /*===========================================================================
1823  * FUNCTION   : openCamera
1824  *
1825  * DESCRIPTION: open camera
1826  *
1827  * PARAMETERS :
1828  *   @hw_device  : double ptr for camera device struct
1829  *
1830  * RETURN     : int32_t type of status
1831  *              NO_ERROR  -- success
1832  *              none-zero failure code
1833  *==========================================================================*/
openCamera(struct hw_device_t ** hw_device)1834 int QCamera2HardwareInterface::openCamera(struct hw_device_t **hw_device)
1835 {
1836     KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_OPENCAMERA);
1837     int rc = NO_ERROR;
1838     if (mCameraOpened) {
1839         *hw_device = NULL;
1840         LOGE("Permission Denied");
1841         return PERMISSION_DENIED;
1842     }
1843     LOGI("[KPI Perf]: E PROFILE_OPEN_CAMERA camera id %d",
1844             mCameraId);
1845 
1846     m_perfLockMgr.acquirePerfLock(PERF_LOCK_OPEN_CAMERA);
1847 
1848     rc = openCamera();
1849     if (rc == NO_ERROR){
1850         *hw_device = &mCameraDevice.common;
1851         if (m_thermalAdapter.init(this) != 0) {
1852           LOGW("Init thermal adapter failed");
1853         }
1854     }
1855     else
1856         *hw_device = NULL;
1857 
1858     LOGI("[KPI Perf]: X PROFILE_OPEN_CAMERA camera id %d, rc: %d",
1859             mCameraId, rc);
1860 
1861     return rc;
1862 }
1863 
1864 /*===========================================================================
1865  * FUNCTION   : openCamera
1866  *
1867  * DESCRIPTION: open camera
1868  *
1869  * PARAMETERS : none
1870  *
1871  * RETURN     : int32_t type of status
1872  *              NO_ERROR  -- success
1873  *              none-zero failure code
1874  *==========================================================================*/
openCamera()1875 int QCamera2HardwareInterface::openCamera()
1876 {
1877     int32_t rc = NO_ERROR;
1878     char value[PROPERTY_VALUE_MAX];
1879 
1880     if (mCameraHandle) {
1881         LOGE("Failure: Camera already opened");
1882         return ALREADY_EXISTS;
1883     }
1884 
1885     rc = QCameraFlash::getInstance().reserveFlashForCamera(mCameraId);
1886     if (rc < 0) {
1887         LOGE("Failed to reserve flash for camera id: %d",
1888                 mCameraId);
1889         return UNKNOWN_ERROR;
1890     }
1891 
1892     // alloc param buffer
1893     DeferWorkArgs args;
1894     memset(&args, 0, sizeof(args));
1895     mParamAllocJob = queueDeferredWork(CMD_DEF_PARAM_ALLOC, args);
1896     if (mParamAllocJob == 0) {
1897         LOGE("Failed queueing PARAM_ALLOC job");
1898         return -ENOMEM;
1899     }
1900 
1901     if (gCamCapability[mCameraId] != NULL) {
1902         // allocate metadata buffers
1903         DeferWorkArgs args;
1904         DeferMetadataAllocArgs metadataAllocArgs;
1905 
1906         memset(&args, 0, sizeof(args));
1907         memset(&metadataAllocArgs, 0, sizeof(metadataAllocArgs));
1908 
1909         uint32_t padding =
1910                 gCamCapability[mCameraId]->padding_info.plane_padding;
1911         metadataAllocArgs.size = PAD_TO_SIZE(sizeof(metadata_buffer_t),
1912                 padding);
1913         metadataAllocArgs.bufferCnt = CAMERA_MIN_METADATA_BUFFERS;
1914         args.metadataAllocArgs = metadataAllocArgs;
1915 
1916         mMetadataAllocJob = queueDeferredWork(CMD_DEF_METADATA_ALLOC, args);
1917         if (mMetadataAllocJob == 0) {
1918             LOGE("Failed to allocate metadata buffer");
1919             rc = -ENOMEM;
1920             goto error_exit1;
1921         }
1922 
1923         rc = camera_open((uint8_t)mCameraId, &mCameraHandle);
1924         if (rc) {
1925             LOGE("camera_open failed. rc = %d, mCameraHandle = %p",
1926                      rc, mCameraHandle);
1927             goto error_exit2;
1928         }
1929 
1930         mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle,
1931                 camEvtHandle,
1932                 (void *) this);
1933     } else {
1934         LOGH("Capabilities not inited, initializing now.");
1935 
1936         rc = camera_open((uint8_t)mCameraId, &mCameraHandle);
1937         if (rc) {
1938             LOGE("camera_open failed. rc = %d, mCameraHandle = %p",
1939                      rc, mCameraHandle);
1940             goto error_exit2;
1941         }
1942 
1943         if(NO_ERROR != initCapabilities(mCameraId,mCameraHandle)) {
1944             LOGE("initCapabilities failed.");
1945             rc = UNKNOWN_ERROR;
1946             goto error_exit3;
1947         }
1948 
1949         mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle,
1950                 camEvtHandle,
1951                 (void *) this);
1952     }
1953     mBundledSnapshot = 0;
1954     mActiveCameras = MM_CAMERA_TYPE_MAIN;
1955     if (isDualCamera()) {
1956         mActiveCameras |= MM_CAMERA_TYPE_AUX;
1957 
1958         // Create and initialize FOV-control object
1959         m_pFovControl = QCameraFOVControl::create(gCamCapability[mCameraId]->main_cam_cap,
1960                 gCamCapability[mCameraId]->aux_cam_cap);
1961         if (m_pFovControl) {
1962             *gCamCapability[mCameraId] = m_pFovControl->consolidateCapabilities(
1963                     gCamCapability[mCameraId]->main_cam_cap,
1964                     gCamCapability[mCameraId]->aux_cam_cap);
1965         } else {
1966             LOGE("FOV-control: Failed to create an object");
1967             rc = NO_MEMORY;
1968             goto error_exit3;
1969         }
1970     }
1971 
1972     // Init params in the background
1973     // 1. It's safe to queue init job, even if alloc job is not yet complete.
1974     // It will be queued to the same thread, so the alloc is guaranteed to
1975     // finish first.
1976     // 2. However, it is not safe to begin param init until after camera is
1977     // open. That is why we wait until after camera open completes to schedule
1978     // this task.
1979     memset(&args, 0, sizeof(args));
1980     mParamInitJob = queueDeferredWork(CMD_DEF_PARAM_INIT, args);
1981     if (mParamInitJob == 0) {
1982         LOGE("Failed queuing PARAM_INIT job");
1983         rc = -ENOMEM;
1984         goto error_exit3;
1985     }
1986 
1987     mCameraOpened = true;
1988 
1989     //Notify display HAL that a camera session is active.
1990     //But avoid calling the same during bootup because camera service might open/close
1991     //cameras at boot time during its initialization and display service will also internally
1992     //wait for camera service to initialize first while calling this display API, resulting in a
1993     //deadlock situation. Since boot time camera open/close calls are made only to fetch
1994     //capabilities, no need of this display bw optimization.
1995     //Use "service.bootanim.exit" property to know boot status.
1996     property_get("service.bootanim.exit", value, "0");
1997     if (atoi(value) == 1) {
1998         pthread_mutex_lock(&gCamLock);
1999         if (gNumCameraSessions++ == 0) {
2000             setCameraLaunchStatus(true);
2001         }
2002         pthread_mutex_unlock(&gCamLock);
2003     }
2004 
2005     // Setprop to decide the time source (whether boottime or monotonic).
2006     // By default, use monotonic time.
2007     property_get("persist.camera.time.monotonic", value, "1");
2008     mBootToMonoTimestampOffset = 0;
2009     if (atoi(value) == 1) {
2010         // if monotonic is set, then need to use time in monotonic.
2011         // So, Measure the clock offset between BOOTTIME and MONOTONIC
2012         // The clock domain source for ISP is BOOTTIME and
2013         // for Video/display is MONOTONIC
2014         // The below offset is used to convert from clock domain of other subsystem
2015         // (video/hardware composer) to that of camera. Assumption is that this
2016         // offset won't change during the life cycle of the camera device. In other
2017         // words, camera device shouldn't be open during CPU suspend.
2018         mBootToMonoTimestampOffset = getBootToMonoTimeOffset();
2019     }
2020     LOGH("mBootToMonoTimestampOffset = %lld", mBootToMonoTimestampOffset);
2021 
2022     memset(value, 0, sizeof(value));
2023     property_get("persist.camera.depth.focus.cb", value, "1");
2024     bDepthAFCallbacks = atoi(value);
2025 
2026     memset(value, 0, sizeof(value));
2027     property_get("persist.camera.cache.optimize", value, "1");
2028     m_bOptimizeCacheOps = atoi(value);
2029 
2030     return NO_ERROR;
2031 
2032 error_exit3:
2033     if(mJpegClientHandle) {
2034         deinitJpegHandle();
2035     }
2036     mCameraHandle->ops->close_camera(mCameraHandle->camera_handle);
2037     mCameraHandle = NULL;
2038 error_exit2:
2039     waitDeferredWork(mMetadataAllocJob);
2040 error_exit1:
2041     waitDeferredWork(mParamAllocJob);
2042     return rc;
2043 
2044 }
2045 
2046 /*===========================================================================
2047  * FUNCTION   : bundleRelatedCameras
2048  *
2049  * DESCRIPTION: bundle cameras to enable syncing of cameras
2050  *
2051  * PARAMETERS :
2052  *   @sync        :indicates whether syncing is On or Off
2053  *
2054  * RETURN     : int32_t type of status
2055  *              NO_ERROR  -- success
2056  *              none-zero failure code
2057  *==========================================================================*/
bundleRelatedCameras(bool syncOn)2058 int QCamera2HardwareInterface::bundleRelatedCameras(bool syncOn)
2059 {
2060     int32_t rc = mParameters.bundleRelatedCameras(syncOn);
2061     if (rc != NO_ERROR) {
2062         LOGE("bundleRelatedCameras failed %d", rc);
2063         return rc;
2064     }
2065     return rc;
2066 }
2067 
2068 /*===========================================================================
2069  * FUNCTION   : getCameraSessionId
2070  *
2071  * DESCRIPTION: gets the backend session Id of this HWI instance
2072  *
2073  * PARAMETERS :
2074  *   @sessionid  : pointer to the output session id
2075  *
2076  * RETURN     : int32_t type of status
2077  *              NO_ERROR  -- success
2078  *              none-zero failure code
2079  *==========================================================================*/
getCameraSessionId(uint32_t * session_id)2080 int QCamera2HardwareInterface::getCameraSessionId(uint32_t* session_id)
2081 {
2082     int32_t rc = NO_ERROR;
2083 
2084     if(session_id != NULL) {
2085         rc = mCameraHandle->ops->get_session_id(mCameraHandle->camera_handle,
2086                 session_id);
2087         LOGD("Getting Camera Session Id %d", *session_id);
2088     } else {
2089         LOGE("Session Id is Null");
2090         return UNKNOWN_ERROR;
2091     }
2092     return rc;
2093 }
2094 
2095 /*===========================================================================
2096  * FUNCTION   : isFrameSyncEnabled
2097  *
2098  * DESCRIPTION: returns whether frame sync is enabled
2099  *
2100  * PARAMETERS : none
2101  *
2102  * RETURN     : bool indicating whether frame sync is enabled
2103  *==========================================================================*/
isFrameSyncEnabled(void)2104 bool QCamera2HardwareInterface::isFrameSyncEnabled(void)
2105 {
2106     return mParameters.isFrameSyncEnabled();
2107 }
2108 
2109 /*===========================================================================
2110  * FUNCTION   : setFrameSyncEnabled
2111  *
2112  * DESCRIPTION: sets whether frame sync is enabled
2113  *
2114  * PARAMETERS :
2115  *   @enable  : flag whether to enable or disable frame sync
2116  *
2117  * RETURN     : int32_t type of status
2118  *              NO_ERROR  -- success
2119  *              none-zero failure code
2120  *==========================================================================*/
setFrameSyncEnabled(bool enable)2121 int32_t QCamera2HardwareInterface::setFrameSyncEnabled(bool enable)
2122 {
2123     return mParameters.setFrameSyncEnabled(enable);
2124 }
2125 
2126 /*===========================================================================
2127  * FUNCTION   : getRelatedCamSyncInfo
2128  *
2129  * DESCRIPTION:returns the related cam sync info for this HWI instance
2130  *
2131  * PARAMETERS :none
2132  *
2133  * RETURN     : const pointer to cam_sync_related_sensors_event_info_t
2134  *==========================================================================*/
2135 const cam_sync_related_sensors_event_info_t*
getRelatedCamSyncInfo(void)2136         QCamera2HardwareInterface::getRelatedCamSyncInfo(void)
2137 {
2138     return mParameters.getRelatedCamSyncInfo();
2139 }
2140 
2141 /*===========================================================================
2142  * FUNCTION   : setRelatedCamSyncInfo
2143  *
2144  * DESCRIPTION:sets the related cam sync info for this HWI instance
2145  *
2146  * PARAMETERS :
2147  *   @info  : ptr to related cam info parameters
2148  *
2149  * RETURN     : int32_t type of status
2150  *              NO_ERROR  -- success
2151  *              none-zero failure code
2152  *==========================================================================*/
setRelatedCamSyncInfo(cam_sync_related_sensors_event_info_t * info)2153 int32_t QCamera2HardwareInterface::setRelatedCamSyncInfo(
2154         cam_sync_related_sensors_event_info_t* info)
2155 {
2156     if(info) {
2157         return mParameters.setRelatedCamSyncInfo(info);
2158     } else {
2159         return BAD_TYPE;
2160     }
2161 }
2162 
2163 /*===========================================================================
2164  * FUNCTION   : getMpoComposition
2165  *
2166  * DESCRIPTION:function to retrieve whether Mpo composition should be enabled
2167  *                    or not
2168  *
2169  * PARAMETERS :none
2170  *
2171  * RETURN     : bool indicates whether mpo composition is enabled or not
2172  *==========================================================================*/
getMpoComposition(void)2173 bool QCamera2HardwareInterface::getMpoComposition(void)
2174 {
2175     LOGH("MpoComposition:%d ", m_bMpoEnabled);
2176     return m_bMpoEnabled;
2177 }
2178 
2179 /*===========================================================================
2180  * FUNCTION   : setMpoComposition
2181  *
2182  * DESCRIPTION:set if Mpo composition should be enabled for this HWI instance
2183  *
2184  * PARAMETERS :
2185  *   @enable  : indicates whether Mpo composition enabled or not
2186  *
2187  * RETURN     : int32_t type of status
2188  *              NO_ERROR  -- success
2189  *              none-zero failure code
2190  *==========================================================================*/
setMpoComposition(bool enable)2191 int32_t QCamera2HardwareInterface::setMpoComposition(bool enable)
2192 {
2193     // By default set Mpo composition to disable
2194     m_bMpoEnabled = false;
2195 
2196     // Enable Mpo composition only if
2197     // 1) frame sync is ON between two cameras and
2198     // 2) any advanced features are not enabled (AOST features) and
2199     // 3) not in recording mode (for liveshot case)
2200     // 4) flash is not needed
2201     if ((getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) &&
2202             !mParameters.isAdvCamFeaturesEnabled() &&
2203             !mParameters.getRecordingHintValue() &&
2204             !mFlashNeeded &&
2205             !isLongshotEnabled()) {
2206         m_bMpoEnabled = enable;
2207         LOGH("MpoComposition:%d ", m_bMpoEnabled);
2208         return NO_ERROR;
2209     } else {
2210         return BAD_TYPE;
2211     }
2212 }
2213 
2214 /*===========================================================================
2215  * FUNCTION   : getRecordingHintValue
2216  *
2217  * DESCRIPTION:function to retrieve recording hint value
2218  *
2219  * PARAMETERS :none
2220  *
2221  * RETURN     : bool indicates whether recording hint is enabled or not
2222  *==========================================================================*/
getRecordingHintValue(void)2223 bool QCamera2HardwareInterface::getRecordingHintValue(void)
2224 {
2225     return mParameters.getRecordingHintValue();
2226 }
2227 
2228 /*===========================================================================
2229  * FUNCTION   : setRecordingHintValue
2230  *
2231  * DESCRIPTION:set recording hint value
2232  *
2233  * PARAMETERS :
2234  *   @enable  : video hint value
2235  *
2236  * RETURN     : int32_t type of status
2237  *              NO_ERROR  -- success
2238  *              none-zero failure code
2239  *==========================================================================*/
setRecordingHintValue(int32_t value)2240 int32_t QCamera2HardwareInterface::setRecordingHintValue(int32_t value)
2241 {
2242     return mParameters.updateRecordingHintValue(value);
2243 }
2244 
2245 /*===========================================================================
2246  * FUNCTION   : closeCamera
2247  *
2248  * DESCRIPTION: close camera
2249  *
2250  * PARAMETERS : none
2251  *
2252  * RETURN     : int32_t type of status
2253  *              NO_ERROR  -- success
2254  *              none-zero failure code
2255  *==========================================================================*/
closeCamera()2256 int QCamera2HardwareInterface::closeCamera()
2257 {
2258     int rc = NO_ERROR;
2259     int i;
2260     char value[PROPERTY_VALUE_MAX];
2261     LOGI("E");
2262     if (!mCameraOpened) {
2263         return NO_ERROR;
2264     }
2265     LOGI("[KPI Perf]: E PROFILE_CLOSE_CAMERA camera id %d",
2266              mCameraId);
2267 
2268     // set open flag to false
2269     mCameraOpened = false;
2270 
2271     // Reset Stream config info
2272     mParameters.setStreamConfigure(false, false, true);
2273 
2274     // deinit Parameters
2275     mParameters.deinit();
2276 
2277     // exit notifier
2278     m_cbNotifier.exit();
2279 
2280     // stop and deinit postprocessor
2281     waitDeferredWork(mReprocJob);
2282     // Close the JPEG session
2283     waitDeferredWork(mJpegJob);
2284     m_postprocessor.stop();
2285     deinitJpegHandle();
2286     m_postprocessor.deinit();
2287     mInitPProcJob = 0; // reset job id, so pproc can be reinited later
2288 
2289     m_thermalAdapter.deinit();
2290 
2291     // delete all channels if not already deleted
2292     for (i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
2293         if (m_channels[i] != NULL) {
2294             m_channels[i]->stop();
2295             delete m_channels[i];
2296             m_channels[i] = NULL;
2297         }
2298     }
2299 
2300     //free all pending api results here
2301     if(m_apiResultList != NULL) {
2302         api_result_list *apiResultList = m_apiResultList;
2303         api_result_list *apiResultListNext;
2304         while (apiResultList != NULL) {
2305             apiResultListNext = apiResultList->next;
2306             free(apiResultList);
2307             apiResultList = apiResultListNext;
2308         }
2309     }
2310 
2311     rc = mCameraHandle->ops->close_camera(mCameraHandle->camera_handle);
2312     mCameraHandle = NULL;
2313 
2314     //Notify display HAL that there is no active camera session
2315     //but avoid calling the same during bootup. Refer to openCamera
2316     //for more details.
2317     property_get("service.bootanim.exit", value, "0");
2318     if (atoi(value) == 1) {
2319         pthread_mutex_lock(&gCamLock);
2320         if (--gNumCameraSessions == 0) {
2321             setCameraLaunchStatus(false);
2322         }
2323         pthread_mutex_unlock(&gCamLock);
2324     }
2325 
2326     if (mExifParams.debug_params) {
2327         free(mExifParams.debug_params);
2328         mExifParams.debug_params = NULL;
2329     }
2330 
2331     if (QCameraFlash::getInstance().releaseFlashFromCamera(mCameraId) != 0) {
2332         LOGD("Failed to release flash for camera id: %d",
2333                 mCameraId);
2334     }
2335 
2336     LOGI("[KPI Perf]: X PROFILE_CLOSE_CAMERA camera id %d, rc: %d",
2337          mCameraId, rc);
2338 
2339     return rc;
2340 }
2341 
2342 #define DATA_PTR(MEM_OBJ,INDEX) MEM_OBJ->getPtr( INDEX )
2343 
2344 
2345 /*===========================================================================
2346  * FUNCTION   : getCapabilities
2347  *
2348  * DESCRIPTION: query camera capability from back-end
2349  *
2350  * PARAMETERS :
2351  *   @ops        : mm-interface ops structure
2352  *   @cam_handle  : camera handle for which we need capability
2353  *
2354  * RETURN     : ptr type of capability structure
2355  *              capability for success
2356  *              NULL for failure
2357  *==========================================================================*/
getCapabilities(mm_camera_ops_t * ops,uint32_t cam_handle)2358 cam_capability_t *QCamera2HardwareInterface::getCapabilities(mm_camera_ops_t *ops,
2359         uint32_t cam_handle)
2360 {
2361     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_GET_CAP);
2362     int rc = NO_ERROR;
2363     QCameraHeapMemory *capabilityHeap = NULL;
2364     cam_capability_t *cap_ptr = NULL;
2365 
2366     if (ops == NULL) {
2367         LOGE("Invalid arguments");
2368         return NULL;
2369     }
2370 
2371     capabilityHeap = new QCameraHeapMemory(1);
2372     if (capabilityHeap == NULL) {
2373         LOGE("creation of capabilityHeap failed");
2374         return NULL;
2375     }
2376 
2377     /* Allocate memory for capability buffer */
2378     rc = capabilityHeap->allocate(1, sizeof(cam_capability_t));
2379     if(rc != OK) {
2380         LOGE("No memory for capability");
2381         goto allocate_failed;
2382     }
2383 
2384     /* Map memory for capability buffer */
2385     memset(DATA_PTR(capabilityHeap,0), 0, sizeof(cam_capability_t));
2386 
2387     cam_buf_map_type_list bufMapList;
2388     rc = QCameraBufferMaps::makeSingletonBufMapList(
2389             CAM_MAPPING_BUF_TYPE_CAPABILITY,
2390             0 /*stream id*/, 0 /*buffer index*/, -1 /*plane index*/,
2391             0 /*cookie*/, capabilityHeap->getFd(0), sizeof(cam_capability_t),
2392             bufMapList, capabilityHeap->getPtr(0));
2393 
2394     if (rc == NO_ERROR) {
2395         rc = ops->map_bufs(cam_handle,
2396                 &bufMapList);
2397     }
2398     if(rc < 0) {
2399         LOGE("failed to map capability buffer");
2400         goto map_failed;
2401     }
2402 
2403     /* Query Capability */
2404     rc = ops->query_capability(cam_handle);
2405     if(rc < 0) {
2406         LOGE("failed to query capability");
2407         rc = FAILED_TRANSACTION;
2408         goto query_failed;
2409     }
2410 
2411     cap_ptr = (cam_capability_t *)malloc(sizeof(cam_capability_t));
2412     if (cap_ptr == NULL) {
2413         LOGE("out of memory");
2414         rc = NO_MEMORY;
2415         goto query_failed;
2416     }
2417 
2418     memset(cap_ptr, 0, sizeof(cam_capability_t));
2419     memcpy(cap_ptr, DATA_PTR(capabilityHeap, 0), sizeof(cam_capability_t));
2420 
2421     int index;
2422     for (index = 0; index < CAM_ANALYSIS_INFO_MAX; index++) {
2423         cam_analysis_info_t *p_analysis_info = &cap_ptr->analysis_info[index];
2424         p_analysis_info->analysis_padding_info.offset_info.offset_x = 0;
2425         p_analysis_info->analysis_padding_info.offset_info.offset_y = 0;
2426     }
2427 
2428 query_failed:
2429     ops->unmap_buf(cam_handle, CAM_MAPPING_BUF_TYPE_CAPABILITY);
2430 map_failed:
2431     capabilityHeap->deallocate();
2432 allocate_failed:
2433     delete capabilityHeap;
2434 
2435     if (rc != NO_ERROR) {
2436         return NULL;
2437     } else {
2438         return cap_ptr;
2439     }
2440 }
2441 
2442 /*===========================================================================
2443  * FUNCTION   : initCapabilities
2444  *
2445  * DESCRIPTION: initialize camera capabilities in static data struct
2446  *
2447  * PARAMETERS :
2448  *   @cameraId  : camera Id
2449  *
2450  * RETURN     : int32_t type of status
2451  *              NO_ERROR  -- success
2452  *              none-zero failure code
2453  *==========================================================================*/
initCapabilities(uint32_t cameraId,mm_camera_vtbl_t * cameraHandle)2454 int QCamera2HardwareInterface::initCapabilities(uint32_t cameraId,
2455         mm_camera_vtbl_t *cameraHandle)
2456 {
2457     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_INIT_CAP);
2458     int rc = 0;
2459     uint32_t handle = 0;
2460 
2461     rc = camera_open((uint8_t)cameraId, &cameraHandle);
2462     if (rc) {
2463         LOGE("camera_open failed. rc = %d", rc);
2464         goto open_failed;
2465     }
2466     if (!cameraHandle) {
2467         LOGE("camera_open failed. cameraHandle = %p", cameraHandle);
2468         goto open_failed;
2469     }
2470 
2471     handle = get_main_camera_handle(cameraHandle->camera_handle);
2472     gCamCapability[cameraId] = getCapabilities(cameraHandle->ops, handle);
2473     if (gCamCapability[cameraId] == NULL) {
2474         rc = FAILED_TRANSACTION;
2475         goto failed_op;
2476     }
2477 
2478     gCamCapability[cameraId]->camera_index = cameraId;
2479     if (is_dual_camera_by_idx(cameraId)) {
2480         handle = get_aux_camera_handle(cameraHandle->camera_handle);
2481         gCamCapability[cameraId]->aux_cam_cap =
2482                 getCapabilities(cameraHandle->ops, handle);
2483         if (gCamCapability[cameraId]->aux_cam_cap == NULL) {
2484             rc = FAILED_TRANSACTION;
2485             free(gCamCapability[cameraId]);
2486             goto failed_op;
2487         }
2488 
2489         // Copy the main camera capability to main_cam_cap struct
2490         gCamCapability[cameraId]->main_cam_cap =
2491                 (cam_capability_t *)malloc(sizeof(cam_capability_t));
2492         if (gCamCapability[cameraId]->main_cam_cap == NULL) {
2493             LOGE("out of memory");
2494             rc = NO_MEMORY;
2495             goto failed_op;
2496         }
2497         memcpy(gCamCapability[cameraId]->main_cam_cap, gCamCapability[cameraId],
2498                 sizeof(cam_capability_t));
2499     }
2500 failed_op:
2501     cameraHandle->ops->close_camera(cameraHandle->camera_handle);
2502     cameraHandle = NULL;
2503 open_failed:
2504     return rc;
2505 }
2506 
2507 /*===========================================================================
2508  * FUNCTION   : getCapabilities
2509  *
2510  * DESCRIPTION: query camera capabilities
2511  *
2512  * PARAMETERS :
2513  *   @cameraId  : camera Id
2514  *   @info      : camera info struct to be filled in with camera capabilities
2515  *
2516  * RETURN     : int type of status
2517  *              NO_ERROR  -- success
2518  *              none-zero failure code
2519  *==========================================================================*/
getCapabilities(uint32_t cameraId,struct camera_info * info,cam_sync_type_t * p_cam_type)2520 int QCamera2HardwareInterface::getCapabilities(uint32_t cameraId,
2521         struct camera_info *info, cam_sync_type_t *p_cam_type)
2522 {
2523     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_GET_CAP);
2524     int rc = NO_ERROR;
2525     struct  camera_info *p_info = NULL;
2526     pthread_mutex_lock(&gCamLock);
2527     p_info = get_cam_info(cameraId, p_cam_type);
2528     p_info->device_version = CAMERA_DEVICE_API_VERSION_1_0;
2529     p_info->static_camera_characteristics = NULL;
2530     memcpy(info, p_info, sizeof (struct camera_info));
2531     pthread_mutex_unlock(&gCamLock);
2532     return rc;
2533 }
2534 
2535 /*===========================================================================
2536  * FUNCTION   : getCamHalCapabilities
2537  *
2538  * DESCRIPTION: get the HAL capabilities structure
2539  *
2540  * PARAMETERS :
2541  *   @cameraId  : camera Id
2542  *
2543  * RETURN     : capability structure of respective camera
2544  *
2545  *==========================================================================*/
getCamHalCapabilities()2546 cam_capability_t* QCamera2HardwareInterface::getCamHalCapabilities()
2547 {
2548     return gCamCapability[mCameraId];
2549 }
2550 
2551 /*===========================================================================
2552  * FUNCTION   : getBufNumForAux
2553  *
2554  * DESCRIPTION: return number of stream buffers needed for aux camera given stream type
2555  *
2556  * PARAMETERS :
2557  *   @stream_type  : type of stream
2558  *
2559  * RETURN     : number of buffers needed
2560  * NOTE     :  Based on the use cases and auxillary camera type,
2561                     we can decide buffer count
2562  *==========================================================================*/
getBufNumForAux(cam_stream_type_t stream_type)2563 uint8_t QCamera2HardwareInterface::getBufNumForAux(cam_stream_type_t stream_type)
2564 {
2565     if (!isDualCamera()) {
2566         return 0;
2567     }
2568 
2569     uint8_t bufferCnt = 1;
2570     switch (stream_type) {
2571     case CAM_STREAM_TYPE_PREVIEW:
2572     case CAM_STREAM_TYPE_VIDEO:
2573     case CAM_STREAM_TYPE_SNAPSHOT:
2574     case CAM_STREAM_TYPE_METADATA:
2575     case CAM_STREAM_TYPE_CALLBACK:
2576     case CAM_STREAM_TYPE_ANALYSIS:
2577     case CAM_STREAM_TYPE_POSTVIEW:
2578     case CAM_STREAM_TYPE_RAW:
2579     case CAM_STREAM_TYPE_OFFLINE_PROC:
2580     case CAM_STREAM_TYPE_DEFAULT:
2581     case CAM_STREAM_TYPE_MAX:
2582         //For wide & tele, we use same buffer count premary and aux streams.
2583         bufferCnt = getBufNumRequired(stream_type);
2584         break;
2585     default:
2586         break;
2587     }
2588     LOGH("Buffer Cnt for Aux Camera : %d", bufferCnt);
2589     return bufferCnt;
2590 }
2591 
2592 /*===========================================================================
2593  * FUNCTION   : getBufNumRequired
2594  *
2595  * DESCRIPTION: return number of stream buffers needed for given stream type
2596  *
2597  * PARAMETERS :
2598  *   @stream_type  : type of stream
2599  *
2600  * RETURN     : number of buffers needed
2601  *==========================================================================*/
getBufNumRequired(cam_stream_type_t stream_type)2602 uint8_t QCamera2HardwareInterface::getBufNumRequired(cam_stream_type_t stream_type)
2603 {
2604     int bufferCnt = 0;
2605     int minCaptureBuffers = mParameters.getNumOfSnapshots();
2606     char value[PROPERTY_VALUE_MAX];
2607     bool raw_yuv = false;
2608     int persist_cnt = 0;
2609     int minPrevFps, maxPrevFps;
2610 
2611     int zslQBuffers = mParameters.getZSLQueueDepth();
2612 
2613     int minCircularBufNum = mParameters.getMaxUnmatchedFramesInQueue() +
2614                             CAMERA_MIN_JPEG_ENCODING_BUFFERS;
2615 
2616     int maxStreamBuf = minCaptureBuffers + mParameters.getMaxUnmatchedFramesInQueue() +
2617                        mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2618                        mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2619                        mParameters.getNumOfExtraBuffersForImageProc() +
2620                        EXTRA_ZSL_PREVIEW_STREAM_BUF;
2621 
2622     int minUndequeCount = 0;
2623     if (!isNoDisplayMode()) {
2624         if(mPreviewWindow != NULL) {
2625             if (mPreviewWindow->get_min_undequeued_buffer_count(mPreviewWindow,&minUndequeCount)
2626                 != 0) {
2627                 LOGW("get_min_undequeued_buffer_count  failed");
2628                 //TODO: hardcoded because MIN_UNDEQUEUED_BUFFERS not defined
2629                 //minUndequeCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS;
2630                 minUndequeCount = MIN_UNDEQUEUED_BUFFERS;
2631             }
2632         } else {
2633             //preview window might not be set at this point. So, query directly
2634             //from BufferQueue implementation of gralloc buffers.
2635             //minUndequeCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS;
2636             //hardcoded because MIN_UNDEQUEUED_BUFFERS not defined. REVISIT
2637             minUndequeCount = MIN_UNDEQUEUED_BUFFERS;
2638         }
2639         if (minUndequeCount != MIN_UNDEQUEUED_BUFFERS) {
2640             // minUndequeCount from valid preview window != hardcoded MIN_UNDEQUEUED_BUFFERS
2641             // and so change the MACRO as per minUndequeCount
2642             LOGW("WARNING : minUndequeCount(%d) != hardcoded value(%d)",
2643                      minUndequeCount, MIN_UNDEQUEUED_BUFFERS);
2644         }
2645     }
2646 
2647     LOGD("minCaptureBuffers = %d zslQBuffers = %d minCircularBufNum = %d"
2648             "maxStreamBuf = %d minUndequeCount = %d",
2649             minCaptureBuffers, zslQBuffers, minCircularBufNum,
2650             maxStreamBuf, minUndequeCount);
2651     // Get buffer count for the particular stream type
2652     switch (stream_type) {
2653     case CAM_STREAM_TYPE_PREVIEW:
2654         {
2655             if (mParameters.isZSLMode()) {
2656                 // We need to add two extra streming buffers to add
2657                 // flexibility in forming matched super buf in ZSL queue.
2658                 // with number being 'zslQBuffers + minCircularBufNum'
2659                 // we see preview buffers sometimes get dropped at CPP
2660                 // and super buf is not forming in ZSL Q for long time.
2661 
2662                 bufferCnt = zslQBuffers + minCircularBufNum +
2663                         mParameters.getNumOfExtraBuffersForImageProc() +
2664                         mParameters.getNumOfExtraBuffersForPreview() +
2665                         mParameters.getNumOfExtraHDRInBufsIfNeeded();
2666                 if (isDualCamera()) {
2667                     bufferCnt += zslQBuffers;
2668                 }
2669             } else {
2670                 bufferCnt = CAMERA_MIN_STREAMING_BUFFERS +
2671                         mParameters.getMaxUnmatchedFramesInQueue() +
2672                         mParameters.getNumOfExtraBuffersForPreview();
2673             }
2674             // ISP allocates native preview buffers and so reducing same from HAL allocation
2675             if (bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS )
2676                 bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS;
2677 
2678             // Extra ZSL preview frames are not needed for HFR case.
2679             // Thumbnail will not be derived from preview for HFR live snapshot case.
2680             if ((mParameters.getRecordingHintValue() == true)
2681                     && (!mParameters.isHfrMode())) {
2682                 bufferCnt += EXTRA_ZSL_PREVIEW_STREAM_BUF;
2683             }
2684             //Adding Extra preview buffers for 60FPS usecase.
2685             mParameters.getPreviewFpsRange(&minPrevFps, &maxPrevFps);
2686             if (maxPrevFps > CAMERA_DEFAULT_FPS) {
2687                 bufferCnt += CAMERA_MIN_DISPLAY_BUFFERS;
2688             }
2689 
2690             // Add the display minUndequeCount count on top of camera requirement
2691             bufferCnt += minUndequeCount;
2692 
2693             property_get("persist.camera.preview_yuv", value, "0");
2694             persist_cnt = atoi(value);
2695             if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM)
2696                     && (bufferCnt < persist_cnt)) {
2697                 bufferCnt = persist_cnt;
2698             }
2699         }
2700         break;
2701     case CAM_STREAM_TYPE_POSTVIEW:
2702         {
2703             bufferCnt = minCaptureBuffers +
2704                         mParameters.getMaxUnmatchedFramesInQueue() +
2705                         mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2706                         mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2707                         mParameters.getNumOfExtraBuffersForImageProc();
2708 
2709             if (bufferCnt > maxStreamBuf) {
2710                 bufferCnt = maxStreamBuf;
2711             }
2712             bufferCnt += minUndequeCount;
2713         }
2714         break;
2715     case CAM_STREAM_TYPE_SNAPSHOT:
2716         {
2717             if (mParameters.isZSLMode() || mLongshotEnabled) {
2718                 if ((minCaptureBuffers == 1 || mParameters.isUbiRefocus()) &&
2719                         !mLongshotEnabled) {
2720                     // Single ZSL snapshot case
2721                     bufferCnt = zslQBuffers + CAMERA_MIN_STREAMING_BUFFERS +
2722                             mParameters.getNumOfExtraBuffersForImageProc();
2723                 } else {
2724                     // ZSL Burst or Longshot case
2725                     bufferCnt = zslQBuffers + minCircularBufNum +
2726                             mParameters.getNumOfExtraBuffersForImageProc();
2727                 }
2728                 if (getSensorType() == CAM_SENSOR_YUV && bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS) {
2729                     //ISP allocates native buffers in YUV case
2730                     bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS;
2731                 }
2732                 if (isDualCamera()) {
2733                     bufferCnt += zslQBuffers;
2734                 }
2735             } else {
2736                 bufferCnt = minCaptureBuffers +
2737                             mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2738                             mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2739                             mParameters.getNumOfExtraBuffersForImageProc();
2740 
2741                 if (bufferCnt > maxStreamBuf) {
2742                     bufferCnt = maxStreamBuf;
2743                 }
2744             }
2745         }
2746         break;
2747     case CAM_STREAM_TYPE_RAW:
2748         property_get("persist.camera.raw_yuv", value, "0");
2749         raw_yuv = atoi(value) > 0 ? true : false;
2750 
2751         if (isRdiMode() || raw_yuv || isSecureMode()) {
2752             bufferCnt = zslQBuffers + minCircularBufNum;
2753         } else if (mParameters.isZSLMode()) {
2754             bufferCnt = zslQBuffers + minCircularBufNum;
2755             if (getSensorType() == CAM_SENSOR_YUV && bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS) {
2756                 //ISP allocates native buffers in YUV case
2757                 bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS;
2758             }
2759 
2760         } else {
2761             bufferCnt = minCaptureBuffers +
2762                         mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2763                         mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2764                         mParameters.getNumOfExtraBuffersForImageProc();
2765 
2766             if (bufferCnt > maxStreamBuf) {
2767                 bufferCnt = maxStreamBuf;
2768             }
2769         }
2770 
2771         property_get("persist.camera.preview_raw", value, "0");
2772         persist_cnt = atoi(value);
2773         if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM)
2774                 && (bufferCnt < persist_cnt)) {
2775             bufferCnt = persist_cnt;
2776         }
2777         property_get("persist.camera.video_raw", value, "0");
2778         persist_cnt = atoi(value);
2779         if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM)
2780                 && (bufferCnt < persist_cnt)) {
2781             bufferCnt = persist_cnt;
2782         }
2783 
2784         break;
2785     case CAM_STREAM_TYPE_VIDEO:
2786         {
2787             if (mParameters.getBufBatchCount()) {
2788                 //Video Buffer in case of HFR or camera batching..
2789                 bufferCnt = CAMERA_MIN_CAMERA_BATCH_BUFFERS;
2790             } else if (mParameters.getVideoBatchSize()) {
2791                 //Video Buffer count only for HAL to HAL batching.
2792                 bufferCnt = (CAMERA_MIN_VIDEO_BATCH_BUFFERS
2793                         * mParameters.getVideoBatchSize());
2794                 if (bufferCnt < CAMERA_MIN_VIDEO_BUFFERS) {
2795                     bufferCnt = CAMERA_MIN_VIDEO_BUFFERS;
2796                 }
2797             } else {
2798                 // No batching enabled.
2799                 bufferCnt = CAMERA_MIN_VIDEO_BUFFERS;
2800             }
2801 
2802             bufferCnt += mParameters.getNumOfExtraBuffersForVideo();
2803             //if its 4K encoding usecase, then add extra buffer
2804             cam_dimension_t dim;
2805             mParameters.getStreamDimension(CAM_STREAM_TYPE_VIDEO, dim);
2806             if (is4k2kResolution(&dim)) {
2807                  //get additional buffer count
2808                  property_get("vidc.enc.dcvs.extra-buff-count", value, "0");
2809                  bufferCnt += atoi(value);
2810             }
2811         }
2812         break;
2813     case CAM_STREAM_TYPE_METADATA:
2814         {
2815             if (mParameters.isZSLMode()) {
2816                 // MetaData buffers should be >= (Preview buffers-minUndequeCount)
2817                 bufferCnt = zslQBuffers + minCircularBufNum +
2818                             mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2819                             mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2820                             mParameters.getNumOfExtraBuffersForImageProc() +
2821                             EXTRA_ZSL_PREVIEW_STREAM_BUF;
2822                 if (isDualCamera()) {
2823                     bufferCnt += zslQBuffers;
2824                 }
2825             } else {
2826                 bufferCnt = minCaptureBuffers +
2827                             mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2828                             mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2829                             mParameters.getMaxUnmatchedFramesInQueue() +
2830                             CAMERA_MIN_STREAMING_BUFFERS +
2831                             mParameters.getNumOfExtraBuffersForImageProc();
2832 
2833                 if (bufferCnt > zslQBuffers + minCircularBufNum) {
2834                     bufferCnt = zslQBuffers + minCircularBufNum;
2835                 }
2836             }
2837             if (CAMERA_MIN_METADATA_BUFFERS > bufferCnt) {
2838                 bufferCnt = CAMERA_MIN_METADATA_BUFFERS;
2839             }
2840         }
2841         break;
2842     case CAM_STREAM_TYPE_OFFLINE_PROC:
2843         {
2844             bufferCnt = minCaptureBuffers;
2845             // One of the ubifocus buffers is miscellaneous buffer
2846             if (mParameters.isUbiRefocus()) {
2847                 bufferCnt -= 1;
2848             }
2849             if (mLongshotEnabled) {
2850                 bufferCnt = mParameters.getLongshotStages();
2851             }
2852         }
2853         break;
2854     case CAM_STREAM_TYPE_CALLBACK:
2855         bufferCnt = CAMERA_MIN_CALLBACK_BUFFERS;
2856         break;
2857     case CAM_STREAM_TYPE_ANALYSIS:
2858     case CAM_STREAM_TYPE_DEFAULT:
2859     case CAM_STREAM_TYPE_MAX:
2860     default:
2861         bufferCnt = 0;
2862         break;
2863     }
2864 
2865     LOGH("Buffer count = %d for stream type = %d", bufferCnt, stream_type);
2866     if (CAM_MAX_NUM_BUFS_PER_STREAM < bufferCnt) {
2867         LOGW("Buffer count %d for stream type %d exceeds limit %d",
2868                  bufferCnt, stream_type, CAM_MAX_NUM_BUFS_PER_STREAM);
2869         return CAM_MAX_NUM_BUFS_PER_STREAM;
2870     }
2871 
2872     return (uint8_t)bufferCnt;
2873 }
2874 
2875 /*===========================================================================
2876  * FUNCTION   : getStreamRefCount
2877  *
2878  * DESCRIPTION: return number of instance of stream of stream type
2879  *
2880  * PARAMETERS :
2881  *   @stream_type  : type of stream
2882  *   @cam_type      : Type of camera for this stream
2883  *
2884  * RETURN     : number of stream instances
2885  * NOTE      :  Based on the use cases and auxillary camera type,
2886                      we can decide stream reference count.
2887                      For example in wide and tele use case, we duplicate all stream
2888                      streams from premary to auxillary.
2889  *==========================================================================*/
getStreamRefCount(cam_stream_type_t stream_type,uint32_t cam_type)2890 uint8_t QCamera2HardwareInterface::getStreamRefCount(cam_stream_type_t stream_type,
2891         uint32_t cam_type)
2892 {
2893     uint8_t ref_cnt = 1;
2894 
2895     if (cam_type != MM_CAMERA_DUAL_CAM) {
2896         return ref_cnt;
2897     }
2898 
2899     switch (stream_type) {
2900     case CAM_STREAM_TYPE_PREVIEW:
2901     case CAM_STREAM_TYPE_SNAPSHOT:
2902     case CAM_STREAM_TYPE_VIDEO:
2903     case CAM_STREAM_TYPE_METADATA:
2904     case CAM_STREAM_TYPE_ANALYSIS:
2905     case CAM_STREAM_TYPE_CALLBACK:
2906         if (isDualCamera()) {
2907             ref_cnt++;
2908         }
2909         break;
2910     case CAM_STREAM_TYPE_POSTVIEW:
2911     case CAM_STREAM_TYPE_RAW:
2912     case CAM_STREAM_TYPE_OFFLINE_PROC:
2913     case CAM_STREAM_TYPE_DEFAULT:
2914     case CAM_STREAM_TYPE_MAX:
2915     default:
2916         break;
2917     }
2918     return ref_cnt;
2919 }
2920 
2921 /*===========================================================================
2922  * FUNCTION   : getCamHandleForChannel
2923  *
2924  * DESCRIPTION: return actual camera handle based on use case
2925  *
2926  * PARAMETERS :
2927  *   @ch_type  : type of channel
2928  *
2929  * RETURN     : uint32_t type camera handle
2930  * NOTE :  Based on the use cases and auxillary camera type, we can decide cam handle for channel.
2931                  Incase, we want to avoid any channel for auxillary camera, we can decide here
2932  *==========================================================================*/
getCamHandleForChannel(qcamera_ch_type_enum_t ch_type)2933 uint32_t QCamera2HardwareInterface::getCamHandleForChannel(qcamera_ch_type_enum_t ch_type)
2934 {
2935     uint32_t handle = 0;
2936     if (!isDualCamera()) {
2937         return mCameraHandle->camera_handle;
2938     }
2939 
2940     /*Based on the use case, decide camera handle for channel*/
2941     switch (ch_type) {
2942     case QCAMERA_CH_TYPE_ZSL:
2943     case QCAMERA_CH_TYPE_CAPTURE:
2944     case QCAMERA_CH_TYPE_PREVIEW:
2945     case QCAMERA_CH_TYPE_VIDEO:
2946     case QCAMERA_CH_TYPE_SNAPSHOT:
2947     case QCAMERA_CH_TYPE_RAW:
2948     case QCAMERA_CH_TYPE_METADATA:
2949     case QCAMERA_CH_TYPE_ANALYSIS:
2950     case QCAMERA_CH_TYPE_CALLBACK:
2951     case QCAMERA_CH_TYPE_MAX:
2952     default:
2953         handle = mCameraHandle->camera_handle;
2954         break;
2955     case QCAMERA_CH_TYPE_REPROCESSING:
2956         if (!mParameters.isDCmAsymmetricSnapMode()) {
2957             handle = get_main_camera_handle(mCameraHandle->camera_handle);
2958         } else {
2959             /*In Asymmetric mode, we create 2 reproc channels. But
2960                      one stream is added per channel */
2961             handle = mCameraHandle->camera_handle;
2962         }
2963         break;
2964     }
2965     return handle;
2966 }
2967 
2968 /*===========================================================================
2969  * FUNCTION   : allocateStreamBuf
2970  *
2971  * DESCRIPTION: alocate stream buffers
2972  *
2973  * PARAMETERS :
2974  *   @stream_type  : type of stream
2975  *   @size         : size of buffer
2976  *   @stride       : stride of buffer
2977  *   @scanline     : scanline of buffer
2978  *   @bufferCnt    : [IN/OUT] minimum num of buffers to be allocated.
2979  *                   could be modified during allocation if more buffers needed
2980  *
2981  * RETURN     : ptr to a memory obj that holds stream buffers.
2982  *              NULL if failed
2983  *==========================================================================*/
allocateStreamBuf(cam_stream_type_t stream_type,size_t size,int stride,int scanline,uint8_t & bufferCnt)2984 QCameraMemory *QCamera2HardwareInterface::allocateStreamBuf(
2985         cam_stream_type_t stream_type, size_t size, int stride, int scanline,
2986         uint8_t &bufferCnt)
2987 {
2988     int rc = NO_ERROR;
2989     QCameraMemory *mem = NULL;
2990     bool bCachedMem = QCAMERA_ION_USE_CACHE;
2991     bool bPoolMem = false;
2992     char value[PROPERTY_VALUE_MAX];
2993     property_get("persist.camera.mem.usepool", value, "1");
2994     if (atoi(value) == 1) {
2995         bPoolMem = true;
2996     }
2997 
2998     // Allocate stream buffer memory object
2999     switch (stream_type) {
3000     case CAM_STREAM_TYPE_PREVIEW:
3001         {
3002             if (isNoDisplayMode()) {
3003                 mem = new QCameraStreamMemory(mGetMemory,
3004                         mCallbackCookie,
3005                         bCachedMem,
3006                         (bPoolMem) ? &m_memoryPool : NULL,
3007                         stream_type);
3008             } else {
3009                 cam_dimension_t dim;
3010                 int minFPS, maxFPS;
3011                 QCameraGrallocMemory *grallocMemory = NULL;
3012 
3013                 if (isSecureMode()) {
3014                     grallocMemory = new QCameraGrallocMemory(mGetMemory, mCallbackCookie, QCAMERA_MEM_TYPE_SECURE);
3015                 }else {
3016                     grallocMemory = new QCameraGrallocMemory(mGetMemory, mCallbackCookie);
3017                 }
3018 
3019                 mParameters.getStreamDimension(stream_type, dim);
3020                 /* we are interested only in maxfps here */
3021                 mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
3022                 int usage = 0;
3023                 if(mParameters.isUBWCEnabled()) {
3024                     cam_format_t fmt;
3025                     mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW,fmt);
3026                     if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
3027                         usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC ;
3028                     }
3029                 }
3030                 if (grallocMemory) {
3031                     grallocMemory->setMappable(
3032                             CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS);
3033                     grallocMemory->setWindowInfo(mPreviewWindow,
3034                             dim.width,dim.height, stride, scanline,
3035                             mParameters.getPreviewHalPixelFormat(),
3036                             maxFPS, usage);
3037                     pthread_mutex_lock(&mGrallocLock);
3038                     if (bufferCnt > CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS) {
3039                         mEnqueuedBuffers = (bufferCnt -
3040                                 CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS);
3041                     } else {
3042                         mEnqueuedBuffers = 0;
3043                     }
3044                     pthread_mutex_unlock(&mGrallocLock);
3045                 }
3046                 mem = grallocMemory;
3047             }
3048         }
3049         break;
3050     case CAM_STREAM_TYPE_POSTVIEW:
3051         {
3052             if (isNoDisplayMode() || isPreviewRestartEnabled()) {
3053                 mem = new QCameraStreamMemory(mGetMemory, mCallbackCookie, bCachedMem);
3054             } else {
3055                 cam_dimension_t dim;
3056                 int minFPS, maxFPS;
3057                 QCameraGrallocMemory *grallocMemory =
3058                         new QCameraGrallocMemory(mGetMemory, mCallbackCookie);
3059 
3060                 mParameters.getStreamDimension(stream_type, dim);
3061                 /* we are interested only in maxfps here */
3062                 mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
3063                 if (grallocMemory) {
3064                     grallocMemory->setWindowInfo(mPreviewWindow, dim.width,
3065                             dim.height, stride, scanline,
3066                             mParameters.getPreviewHalPixelFormat(), maxFPS);
3067                 }
3068                 mem = grallocMemory;
3069             }
3070         }
3071         break;
3072     case CAM_STREAM_TYPE_ANALYSIS:
3073     case CAM_STREAM_TYPE_SNAPSHOT:
3074     case CAM_STREAM_TYPE_OFFLINE_PROC:
3075         mem = new QCameraStreamMemory(mGetMemory,
3076                 mCallbackCookie,
3077                 bCachedMem,
3078                 (bPoolMem) ? &m_memoryPool : NULL,
3079                 stream_type);
3080         break;
3081     case CAM_STREAM_TYPE_RAW:
3082         if(isSecureMode()) {
3083             mem = new QCameraStreamMemory(mGetMemory,
3084                     mCallbackCookie,
3085                     bCachedMem,
3086                     (bPoolMem) ? &m_memoryPool : NULL,
3087                     stream_type,
3088                     QCAMERA_MEM_TYPE_SECURE);
3089             LOGH("Allocating %d secure buffers of size %d ", bufferCnt, size);
3090         } else {
3091             mem = new QCameraStreamMemory(mGetMemory,
3092                     mCallbackCookie,
3093                     bCachedMem,
3094                     (bPoolMem) ? &m_memoryPool : NULL,
3095                     stream_type);
3096         }
3097         break;
3098     case CAM_STREAM_TYPE_METADATA:
3099         {
3100             if (mMetadataMem == NULL) {
3101                 mem = new QCameraMetadataStreamMemory(QCAMERA_ION_USE_CACHE);
3102             } else {
3103                 mem = mMetadataMem;
3104                 mMetadataMem = NULL;
3105 
3106                 int32_t numAdditionalBuffers = bufferCnt - mem->getCnt();
3107                 if (numAdditionalBuffers > 0) {
3108                     rc = mem->allocateMore(numAdditionalBuffers, size);
3109                     if (rc != NO_ERROR) {
3110                         LOGE("Failed to allocate additional buffers, "
3111                                 "but attempting to proceed.");
3112                     }
3113                 }
3114                 bufferCnt = mem->getCnt();
3115                 // The memory is already allocated  and initialized, so
3116                 // simply return here.
3117                 return mem;
3118             }
3119         }
3120         break;
3121     case CAM_STREAM_TYPE_VIDEO:
3122         {
3123             //Use uncached allocation by default
3124             if (mParameters.isVideoBuffersCached() || mParameters.isSeeMoreEnabled() ||
3125                     mParameters.isHighQualityNoiseReductionMode()) {
3126                 bCachedMem = QCAMERA_ION_USE_CACHE;
3127             }
3128             else {
3129                 bCachedMem = QCAMERA_ION_USE_NOCACHE;
3130             }
3131 
3132             QCameraVideoMemory *videoMemory = NULL;
3133             int usage = 0;
3134             cam_format_t fmt;
3135 
3136             if (mParameters.getVideoBatchSize()) {
3137                 videoMemory = new QCameraVideoMemory(
3138                         mGetMemory, mCallbackCookie, FALSE, QCAMERA_MEM_TYPE_BATCH);
3139                 if (videoMemory == NULL) {
3140                     LOGE("Out of memory for video batching obj");
3141                     return NULL;
3142                 }
3143                 mParameters.getStreamFormat(CAM_STREAM_TYPE_VIDEO,fmt);
3144                 if (mParameters.isUBWCEnabled() &&
3145                         (fmt == CAM_FORMAT_YUV_420_NV12_UBWC)) {
3146                     usage = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
3147                 }
3148                 videoMemory->setVideoInfo(usage, fmt);
3149                 /*
3150                 *   numFDs = BATCH size
3151                 *  numInts = 5  // OFFSET, SIZE, USAGE, TIMESTAMP, FORMAT
3152                 */
3153                 rc = videoMemory->allocateMeta(
3154                         CAMERA_MIN_VIDEO_BATCH_BUFFERS,
3155                         mParameters.getVideoBatchSize());
3156                 if (rc < 0) {
3157                     delete videoMemory;
3158                     return NULL;
3159                 }
3160             } else {
3161                 videoMemory =
3162                         new QCameraVideoMemory(mGetMemory, mCallbackCookie, bCachedMem);
3163                 if (videoMemory == NULL) {
3164                     LOGE("Out of memory for video obj");
3165                     return NULL;
3166                 }
3167                 mParameters.getStreamFormat(CAM_STREAM_TYPE_VIDEO,fmt);
3168                 if (mParameters.isUBWCEnabled() &&
3169                         (fmt == CAM_FORMAT_YUV_420_NV12_UBWC)) {
3170                     usage = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
3171                 }
3172                 videoMemory->setVideoInfo(usage, fmt);
3173             }
3174             mem = videoMemory;
3175         }
3176         break;
3177     case CAM_STREAM_TYPE_CALLBACK:
3178         mem = new QCameraStreamMemory(mGetMemory,
3179                 mCallbackCookie,
3180                 bCachedMem,
3181                 (bPoolMem) ? &m_memoryPool : NULL,
3182                 stream_type);
3183         break;
3184     case CAM_STREAM_TYPE_DEFAULT:
3185     case CAM_STREAM_TYPE_MAX:
3186     default:
3187         break;
3188     }
3189     if (!mem) {
3190         return NULL;
3191     }
3192 
3193     if (bufferCnt > 0) {
3194         rc = mem->allocate(bufferCnt, size);
3195         if (rc < 0) {
3196             delete mem;
3197             return NULL;
3198         }
3199         bufferCnt = mem->getCnt();
3200     }
3201     LOGH("rc = %d type = %d count = %d size = %d cache = %d, pool = %d mEnqueuedBuffers = %d",
3202             rc, stream_type, bufferCnt, size, bCachedMem, bPoolMem, mEnqueuedBuffers);
3203     return mem;
3204 }
3205 
3206 /*===========================================================================
3207  * FUNCTION   : allocateMoreStreamBuf
3208  *
3209  * DESCRIPTION: alocate more stream buffers from the memory object
3210  *
3211  * PARAMETERS :
3212  *   @mem_obj      : memory object ptr
3213  *   @size         : size of buffer
3214  *   @bufferCnt    : [IN/OUT] additional number of buffers to be allocated.
3215  *                   output will be the number of total buffers
3216  *
3217  * RETURN     : int32_t type of status
3218  *              NO_ERROR  -- success
3219  *              none-zero failure code
3220  *==========================================================================*/
allocateMoreStreamBuf(QCameraMemory * mem_obj,size_t size,uint8_t & bufferCnt)3221 int32_t QCamera2HardwareInterface::allocateMoreStreamBuf(
3222         QCameraMemory *mem_obj, size_t size, uint8_t &bufferCnt)
3223 {
3224     int rc = NO_ERROR;
3225 
3226     if (bufferCnt > 0) {
3227         rc = mem_obj->allocateMore(bufferCnt, size);
3228         bufferCnt = mem_obj->getCnt();
3229     }
3230     return rc;
3231 }
3232 
3233 /*===========================================================================
3234  * FUNCTION   : allocateMiscBuf
3235  *
3236  * DESCRIPTION: alocate miscellaneous buffer
3237  *
3238  * PARAMETERS :
3239  *   @streamInfo  : stream info
3240  *
3241  * RETURN     : ptr to a memory obj that holds stream info buffer.
3242  *              NULL if failed
3243  *==========================================================================*/
allocateMiscBuf(cam_stream_info_t * streamInfo)3244 QCameraHeapMemory *QCamera2HardwareInterface::allocateMiscBuf(
3245         cam_stream_info_t *streamInfo)
3246 {
3247     int rc = NO_ERROR;
3248     uint8_t bufNum = 0;
3249     size_t bufSize = 0;
3250     QCameraHeapMemory *miscBuf = NULL;
3251     cam_feature_mask_t feature_mask =
3252             streamInfo->reprocess_config.pp_feature_config.feature_mask;
3253 
3254     switch (streamInfo->stream_type) {
3255     case CAM_STREAM_TYPE_OFFLINE_PROC:
3256         if (CAM_QCOM_FEATURE_TRUEPORTRAIT & feature_mask) {
3257             bufNum = 1;
3258             bufSize = mParameters.getTPMaxMetaSize();
3259         } else if (CAM_QCOM_FEATURE_REFOCUS & feature_mask) {
3260             bufNum = 1;
3261             bufSize = mParameters.getRefocusMaxMetaSize();
3262         }
3263         break;
3264     default:
3265         break;
3266     }
3267 
3268     if (bufNum && bufSize) {
3269         miscBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
3270 
3271         if (!miscBuf) {
3272             LOGE("Unable to allocate miscBuf object");
3273             return NULL;
3274         }
3275 
3276         rc = miscBuf->allocate(bufNum, bufSize);
3277         if (rc < 0) {
3278             LOGE("Failed to allocate misc buffer memory");
3279             delete miscBuf;
3280             return NULL;
3281         }
3282     }
3283 
3284     return miscBuf;
3285 }
3286 
3287 /*===========================================================================
3288  * FUNCTION   : initStreamInfoBuf
3289  *
3290  * DESCRIPTION: initialize stream info buffer based on stream type
3291  *
3292  * PARAMETERS :
3293  *   @stream_type  : type of stream
3294  *   @cam_type      : Camera type in case of dual camera
3295  *
3296  * RETURN     : ptr to a memory obj that holds stream info buffer.
3297  *              NULL if failed
3298  *==========================================================================*/
initStreamInfoBuf(cam_stream_type_t stream_type,cam_stream_info_t * streamInfo,uint32_t cam_type)3299 int QCamera2HardwareInterface::initStreamInfoBuf(cam_stream_type_t stream_type,
3300             cam_stream_info_t *streamInfo, uint32_t cam_type)
3301 {
3302     int rc = NO_ERROR;
3303     int32_t dt = 0;
3304     int32_t vc = 0;
3305 
3306     memset(streamInfo, 0, sizeof(cam_stream_info_t));
3307     streamInfo->stream_type = stream_type;
3308     rc = mParameters.getStreamFormat(stream_type, streamInfo->fmt);
3309     rc = mParameters.getStreamDimension(stream_type, streamInfo->dim, cam_type);
3310     rc = mParameters.getStreamRotation(stream_type, streamInfo->pp_config, streamInfo->dim);
3311     streamInfo->num_bufs = getBufNumRequired(stream_type);
3312     streamInfo->buf_cnt = streamInfo->num_bufs;
3313     streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
3314     streamInfo->is_secure = NON_SECURE;
3315     // Initialize cache ops
3316     if (!m_bOptimizeCacheOps) {
3317         streamInfo->cache_ops = CAM_STREAM_CACHE_OPS_DISABLED;
3318     } else {
3319         streamInfo->cache_ops = CAM_STREAM_CACHE_OPS_HONOUR_FLAGS;
3320     }
3321 
3322     switch (stream_type) {
3323     case CAM_STREAM_TYPE_SNAPSHOT:
3324         if ((mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) ||
3325             mLongshotEnabled) {
3326             streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
3327         } else {
3328             streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
3329             streamInfo->num_of_burst = (uint8_t)
3330                     (mParameters.getNumOfSnapshots()
3331                         + mParameters.getNumOfExtraHDRInBufsIfNeeded()
3332                         - mParameters.getNumOfExtraHDROutBufsIfNeeded()
3333                         + mParameters.getNumOfExtraBuffersForImageProc());
3334         }
3335         break;
3336     case CAM_STREAM_TYPE_RAW: {
3337             char value[PROPERTY_VALUE_MAX];
3338             bool raw_yuv = false;
3339             property_get("persist.camera.raw_yuv", value, "0");
3340             raw_yuv = atoi(value) > 0 ? true : false;
3341             if ((mParameters.isZSLMode()) || (isRdiMode()) || (raw_yuv) || isSecureMode()) {
3342                 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
3343             } else {
3344                 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
3345                 streamInfo->num_of_burst = mParameters.getNumOfSnapshots();
3346             }
3347             if (isSecureMode()) {
3348                 streamInfo->is_secure = SECURE;
3349             } else {
3350                 streamInfo->is_secure = NON_SECURE;
3351             }
3352         }
3353         if (CAM_FORMAT_META_RAW_10BIT == streamInfo->fmt) {
3354             mParameters.updateDtVc(&dt, &vc);
3355             if (dt)
3356                 streamInfo->dt = dt;
3357             streamInfo->vc = vc;
3358         }
3359 
3360         break;
3361     case CAM_STREAM_TYPE_POSTVIEW:
3362         if (mLongshotEnabled) {
3363             streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
3364         } else {
3365             streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
3366             streamInfo->num_of_burst = (uint8_t)(mParameters.getNumOfSnapshots()
3367                 + mParameters.getNumOfExtraHDRInBufsIfNeeded()
3368                 - mParameters.getNumOfExtraHDROutBufsIfNeeded()
3369                 + mParameters.getNumOfExtraBuffersForImageProc());
3370         }
3371         break;
3372     case CAM_STREAM_TYPE_VIDEO:
3373         streamInfo->dis_enable = mParameters.isDISEnabled();
3374         if (mParameters.getBufBatchCount()) {
3375             //Update stream info structure with batch mode info
3376             streamInfo->streaming_mode = CAM_STREAMING_MODE_BATCH;
3377             streamInfo->user_buf_info.frame_buf_cnt = mParameters.getBufBatchCount();
3378             streamInfo->user_buf_info.size =
3379                     (uint32_t)(sizeof(struct msm_camera_user_buf_cont_t));
3380             cam_fps_range_t pFpsRange;
3381             mParameters.getHfrFps(pFpsRange);
3382             streamInfo->user_buf_info.frameInterval =
3383                     (long)((1000/pFpsRange.video_max_fps) * 1000);
3384             LOGH("Video Batch Count = %d, interval = %d",
3385                     streamInfo->user_buf_info.frame_buf_cnt,
3386                     streamInfo->user_buf_info.frameInterval);
3387         }
3388         if (mParameters.getRecordingHintValue()) {
3389             if(mParameters.isDISEnabled()) {
3390                 streamInfo->is_type = mParameters.getVideoISType();
3391             } else {
3392                 streamInfo->is_type = IS_TYPE_NONE;
3393             }
3394         }
3395         if (mParameters.isSecureMode()) {
3396             streamInfo->is_secure = SECURE;
3397         }
3398         break;
3399     case CAM_STREAM_TYPE_PREVIEW:
3400         if (mParameters.getRecordingHintValue()) {
3401             if(mParameters.isDISEnabled()) {
3402                 streamInfo->is_type = mParameters.getPreviewISType();
3403             } else {
3404                 streamInfo->is_type = IS_TYPE_NONE;
3405             }
3406         }
3407         if (isSecureMode()) {
3408             streamInfo->is_secure = SECURE;
3409         } else {
3410             streamInfo->is_secure = NON_SECURE;
3411         }
3412         // If SAT enabled, don't add preview stream to Bundled queue
3413         if (isDualCamera()) {
3414             char prop[PROPERTY_VALUE_MAX];
3415             memset(prop, 0, sizeof(prop));
3416             bool satEnabledFlag = FALSE;
3417             property_get("persist.camera.sat.enable", prop, "0");
3418             satEnabledFlag = atoi(prop);
3419             if (satEnabledFlag) {
3420                 streamInfo->noFrameExpected = 1;
3421             }
3422         }
3423         break;
3424     case CAM_STREAM_TYPE_ANALYSIS:
3425         streamInfo->noFrameExpected = 1;
3426         break;
3427     case CAM_STREAM_TYPE_METADATA:
3428         streamInfo->cache_ops = CAM_STREAM_CACHE_OPS_CLEAR_FLAGS;
3429         break;
3430     default:
3431         break;
3432     }
3433 
3434     // Update feature mask
3435     mParameters.updatePpFeatureMask(stream_type);
3436 
3437     // Get feature mask
3438     mParameters.getStreamPpMask(stream_type, streamInfo->pp_config.feature_mask);
3439 
3440     // Update pp config
3441     if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_FLIP) {
3442         int flipMode = mParameters.getFlipMode(stream_type);
3443         if (flipMode > 0) {
3444             streamInfo->pp_config.flip = (uint32_t)flipMode;
3445         }
3446     }
3447     if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_SHARPNESS) {
3448         streamInfo->pp_config.sharpness = mParameters.getSharpness();
3449     }
3450     if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_EFFECT) {
3451         streamInfo->pp_config.effect = mParameters.getEffectValue();
3452     }
3453 
3454     if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_DENOISE2D) {
3455         streamInfo->pp_config.denoise2d.denoise_enable = 1;
3456         streamInfo->pp_config.denoise2d.process_plates =
3457                 mParameters.getDenoiseProcessPlate(CAM_INTF_PARM_WAVELET_DENOISE);
3458     }
3459 
3460     if (!((needReprocess()) && (CAM_STREAM_TYPE_SNAPSHOT == stream_type ||
3461             CAM_STREAM_TYPE_RAW == stream_type))) {
3462         if (gCamCapability[mCameraId]->qcom_supported_feature_mask &
3463                 CAM_QCOM_FEATURE_CROP)
3464             streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
3465         if (gCamCapability[mCameraId]->qcom_supported_feature_mask &
3466                 CAM_QCOM_FEATURE_SCALE)
3467             streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
3468     }
3469     streamInfo->aux_str_info = NULL;
3470 
3471     LOGH("type %d, fmt %d, dim %dx%d, num_bufs %d mask = 0x%x is_type %d\n",
3472            stream_type, streamInfo->fmt, streamInfo->dim.width,
3473            streamInfo->dim.height, streamInfo->num_bufs,
3474            streamInfo->pp_config.feature_mask,
3475            streamInfo->is_type);
3476 
3477     return rc;
3478 }
3479 
3480 /*===========================================================================
3481  * FUNCTION   : allocateStreamInfoBuf
3482  *
3483  * DESCRIPTION: alocate stream info buffer
3484  *
3485  * PARAMETERS :
3486  *   @stream_type  : type of stream
3487  *   @bufCount       : stream info buffer count
3488  *   @cam_type     : Camera type in case of dual camera
3489  *
3490  * RETURN     : ptr to a memory obj that holds stream info buffer.
3491  *              NULL if failed
3492  *==========================================================================*/
allocateStreamInfoBuf(cam_stream_type_t stream_type,uint8_t bufCount,uint32_t cam_type)3493 QCameraHeapMemory *QCamera2HardwareInterface::allocateStreamInfoBuf(
3494         cam_stream_type_t stream_type, uint8_t bufCount, uint32_t cam_type)
3495 {
3496     int rc = NO_ERROR;
3497 
3498     QCameraHeapMemory *streamInfoBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
3499     if (!streamInfoBuf) {
3500         LOGE("allocateStreamInfoBuf: Unable to allocate streamInfo object");
3501         return NULL;
3502     }
3503 
3504     if (bufCount > MM_CAMERA_MAX_CAM_CNT) {
3505         LOGE("buffer count should be lesser than max camera : %d", bufCount);
3506         return NULL;
3507     }
3508     rc = streamInfoBuf->allocate(bufCount, sizeof(cam_stream_info_t));
3509     if (rc < 0) {
3510         LOGE("allocateStreamInfoBuf: Failed to allocate stream info memory");
3511         delete streamInfoBuf;
3512         return NULL;
3513     }
3514 
3515     for (uint8_t i = 0; i < bufCount; i++) {
3516         cam_stream_info_t *streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(i);
3517         memset(streamInfo, 0, sizeof(cam_stream_info_t));
3518         rc = initStreamInfoBuf(stream_type, streamInfo, cam_type);
3519         if (rc < 0) {
3520             LOGE("initStreamInfoBuf failed");
3521             delete streamInfoBuf;
3522             return NULL;
3523         }
3524     }
3525 
3526     cam_stream_info_t *streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(0);
3527     if (bufCount == MM_CAMERA_MAX_CAM_CNT) {
3528         cam_stream_info_t *s_streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(1);
3529         streamInfo->aux_str_info = s_streamInfo;
3530     }
3531 
3532     if (streamInfo->aux_str_info != NULL) {
3533         /*Update StreamInfo for Aux camera*/
3534         streamInfo->aux_str_info->buf_cnt = getBufNumForAux(stream_type);
3535         streamInfo->num_bufs += streamInfo->aux_str_info->buf_cnt;
3536         streamInfo->aux_str_info->num_bufs += streamInfo->aux_str_info->buf_cnt;
3537     }
3538     return streamInfoBuf;
3539 }
3540 
3541 /*===========================================================================
3542  * FUNCTION   : allocateStreamUserBuf
3543  *
3544  * DESCRIPTION: allocate user ptr for stream buffers
3545  *
3546  * PARAMETERS :
3547  *   @streamInfo  : stream info structure
3548  *
3549  * RETURN     : ptr to a memory obj that holds stream info buffer.
3550  *                    NULL if failed
3551 
3552  *==========================================================================*/
allocateStreamUserBuf(cam_stream_info_t * streamInfo)3553 QCameraMemory *QCamera2HardwareInterface::allocateStreamUserBuf(
3554         cam_stream_info_t *streamInfo)
3555 {
3556     int rc = NO_ERROR;
3557     QCameraMemory *mem = NULL;
3558     int size = 0;
3559 
3560     if (streamInfo->streaming_mode != CAM_STREAMING_MODE_BATCH) {
3561         LOGE("Stream is not in BATCH mode. Invalid Stream");
3562         return NULL;
3563     }
3564 
3565     // Allocate stream user buffer memory object
3566     switch (streamInfo->stream_type) {
3567     case CAM_STREAM_TYPE_VIDEO: {
3568         QCameraVideoMemory *video_mem = new QCameraVideoMemory(
3569                 mGetMemory, mCallbackCookie, FALSE, QCAMERA_MEM_TYPE_BATCH);
3570         if (video_mem == NULL) {
3571             LOGE("Out of memory for video obj");
3572             return NULL;
3573         }
3574 
3575         int usage = 0;
3576         cam_format_t fmt;
3577         mParameters.getStreamFormat(CAM_STREAM_TYPE_VIDEO, fmt);
3578         if(mParameters.isUBWCEnabled() && (fmt == CAM_FORMAT_YUV_420_NV12_UBWC)) {
3579             usage = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
3580         }
3581         video_mem->setVideoInfo(usage, fmt);
3582 
3583         /*
3584         *   numFDs = BATCH size
3585         *  numInts = 5  // OFFSET, SIZE, USAGE, TIMESTAMP, FORMAT
3586         */
3587         rc = video_mem->allocateMeta(streamInfo->num_bufs,
3588                 mParameters.getBufBatchCount());
3589         if (rc < 0) {
3590             LOGE("allocateMeta failed");
3591             delete video_mem;
3592             return NULL;
3593         }
3594         mem = static_cast<QCameraMemory *>(video_mem);
3595     }
3596     break;
3597 
3598     case CAM_STREAM_TYPE_PREVIEW:
3599     case CAM_STREAM_TYPE_POSTVIEW:
3600     case CAM_STREAM_TYPE_ANALYSIS:
3601     case CAM_STREAM_TYPE_SNAPSHOT:
3602     case CAM_STREAM_TYPE_RAW:
3603     case CAM_STREAM_TYPE_METADATA:
3604     case CAM_STREAM_TYPE_OFFLINE_PROC:
3605     case CAM_STREAM_TYPE_CALLBACK:
3606         LOGE("Stream type Not supported.for BATCH processing");
3607     break;
3608 
3609     case CAM_STREAM_TYPE_DEFAULT:
3610     case CAM_STREAM_TYPE_MAX:
3611     default:
3612         break;
3613     }
3614     if (!mem) {
3615         LOGE("Failed to allocate mem");
3616         return NULL;
3617     }
3618 
3619     /*Size of this buffer will be number of batch buffer */
3620     size = PAD_TO_SIZE((streamInfo->num_bufs * streamInfo->user_buf_info.size),
3621             CAM_PAD_TO_4K);
3622 
3623     LOGH("Allocating BATCH Buffer count = %d", streamInfo->num_bufs);
3624 
3625     if (size > 0) {
3626         // Allocating one buffer for all batch buffers
3627         rc = mem->allocate(1, size);
3628         if (rc < 0) {
3629             delete mem;
3630             return NULL;
3631         }
3632     }
3633     return mem;
3634 }
3635 
3636 
3637 /*===========================================================================
3638  * FUNCTION   : waitForDeferredAlloc
3639  *
3640  * DESCRIPTION: Wait for deferred allocation, if applicable
3641  *              (applicable only for metadata buffers so far)
3642  *
3643  * PARAMETERS :
3644  *   @stream_type  : type of stream to (possibly) wait for
3645  *
3646  * RETURN     : None
3647  *==========================================================================*/
waitForDeferredAlloc(cam_stream_type_t stream_type)3648 void QCamera2HardwareInterface::waitForDeferredAlloc(cam_stream_type_t stream_type)
3649 {
3650     if (stream_type == CAM_STREAM_TYPE_METADATA) {
3651         waitDeferredWork(mMetadataAllocJob);
3652     }
3653 }
3654 
3655 
3656 /*===========================================================================
3657  * FUNCTION   : setPreviewWindow
3658  *
3659  * DESCRIPTION: set preview window impl
3660  *
3661  * PARAMETERS :
3662  *   @window  : ptr to window ops table struct
3663  *
3664  * RETURN     : int32_t type of status
3665  *              NO_ERROR  -- success
3666  *              none-zero failure code
3667  *==========================================================================*/
setPreviewWindow(struct preview_stream_ops * window)3668 int QCamera2HardwareInterface::setPreviewWindow(
3669         struct preview_stream_ops *window)
3670 {
3671     mPreviewWindow = window;
3672     return NO_ERROR;
3673 }
3674 
3675 /*===========================================================================
3676  * FUNCTION   : setCallBacks
3677  *
3678  * DESCRIPTION: set callbacks impl
3679  *
3680  * PARAMETERS :
3681  *   @notify_cb  : notify cb
3682  *   @data_cb    : data cb
3683  *   @data_cb_timestamp : data cb with time stamp
3684  *   @get_memory : request memory ops table
3685  *   @user       : user data ptr
3686  *
3687  * RETURN     : int32_t type of status
3688  *              NO_ERROR  -- success
3689  *              none-zero failure code
3690  *==========================================================================*/
setCallBacks(camera_notify_callback notify_cb,camera_data_callback data_cb,camera_data_timestamp_callback data_cb_timestamp,camera_request_memory get_memory,void * user)3691 int QCamera2HardwareInterface::setCallBacks(camera_notify_callback notify_cb,
3692                                             camera_data_callback data_cb,
3693                                             camera_data_timestamp_callback data_cb_timestamp,
3694                                             camera_request_memory get_memory,
3695                                             void *user)
3696 {
3697     mNotifyCb        = notify_cb;
3698     mDataCb          = data_cb;
3699     mDataCbTimestamp = data_cb_timestamp;
3700     mGetMemory       = get_memory;
3701     mCallbackCookie  = user;
3702     m_cbNotifier.setCallbacks(notify_cb, data_cb, data_cb_timestamp, user);
3703     return NO_ERROR;
3704 }
3705 
3706 /*===========================================================================
3707  * FUNCTION   : setJpegCallBacks
3708  *
3709  * DESCRIPTION: set JPEG callbacks impl
3710  *
3711  * PARAMETERS :
3712  *   @jpegCb  : Jpeg callback method
3713  *   @callbackCookie    : callback cookie
3714  *
3715  * RETURN     : int32_t type of status
3716  *              NO_ERROR  -- success
3717  *              none-zero failure code
3718  *==========================================================================*/
setJpegCallBacks(jpeg_data_callback jpegCb,void * callbackCookie)3719 void QCamera2HardwareInterface::setJpegCallBacks(jpeg_data_callback jpegCb,
3720                                             void *callbackCookie)
3721 {
3722     LOGH("camera id %d", getCameraId());
3723     mJpegCb        = jpegCb;
3724     mJpegCallbackCookie  = callbackCookie;
3725     m_cbNotifier.setJpegCallBacks(mJpegCb, mJpegCallbackCookie);
3726 }
3727 
3728 /*===========================================================================
3729  * FUNCTION   : enableMsgType
3730  *
3731  * DESCRIPTION: enable msg type impl
3732  *
3733  * PARAMETERS :
3734  *   @msg_type  : msg type mask to be enabled
3735  *
3736  * RETURN     : int32_t type of status
3737  *              NO_ERROR  -- success
3738  *              none-zero failure code
3739  *==========================================================================*/
enableMsgType(int32_t msg_type)3740 int QCamera2HardwareInterface::enableMsgType(int32_t msg_type)
3741 {
3742     int32_t rc = NO_ERROR;
3743 
3744     if (mParameters.isUBWCEnabled()) {
3745         /*Need Special CALLBACK stream incase application requesting for
3746               Preview callback  in UBWC case*/
3747         if (!(msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) &&
3748                 (msg_type & CAMERA_MSG_PREVIEW_FRAME)) {
3749             // Start callback channel only when preview/zsl channel is active
3750             QCameraChannel* previewCh = NULL;
3751             if (isZSLMode() && (getRecordingHintValue() != true)) {
3752                 previewCh = m_channels[QCAMERA_CH_TYPE_ZSL];
3753             } else {
3754                 previewCh = m_channels[QCAMERA_CH_TYPE_PREVIEW];
3755             }
3756             QCameraChannel* callbackCh = m_channels[QCAMERA_CH_TYPE_CALLBACK];
3757             if ((callbackCh != NULL) &&
3758                     (previewCh != NULL) && previewCh->isActive()) {
3759                 rc = startChannel(QCAMERA_CH_TYPE_CALLBACK);
3760                 if (rc != NO_ERROR) {
3761                     LOGE("START Callback Channel failed");
3762                 }
3763             }
3764         }
3765     }
3766     mMsgEnabled |= msg_type;
3767     LOGH("(0x%x) : mMsgEnabled = 0x%x rc = %d", msg_type , mMsgEnabled, rc);
3768     return rc;
3769 }
3770 
3771 /*===========================================================================
3772  * FUNCTION   : disableMsgType
3773  *
3774  * DESCRIPTION: disable msg type impl
3775  *
3776  * PARAMETERS :
3777  *   @msg_type  : msg type mask to be disabled
3778  *
3779  * RETURN     : int32_t type of status
3780  *              NO_ERROR  -- success
3781  *              none-zero failure code
3782  *==========================================================================*/
disableMsgType(int32_t msg_type)3783 int QCamera2HardwareInterface::disableMsgType(int32_t msg_type)
3784 {
3785     int32_t rc = NO_ERROR;
3786 
3787     if (mParameters.isUBWCEnabled()) {
3788         /*STOP CALLBACK STREAM*/
3789         if ((msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) &&
3790                 (msg_type & CAMERA_MSG_PREVIEW_FRAME)) {
3791             // Stop callback channel only if it is active
3792             if ((m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL) &&
3793                    (m_channels[QCAMERA_CH_TYPE_CALLBACK]->isActive())) {
3794                 rc = stopChannel(QCAMERA_CH_TYPE_CALLBACK);
3795                 if (rc != NO_ERROR) {
3796                     LOGE("STOP Callback Channel failed");
3797                 }
3798             }
3799         }
3800     }
3801     mMsgEnabled &= ~msg_type;
3802     LOGH("(0x%x) : mMsgEnabled = 0x%x rc = %d", msg_type , mMsgEnabled, rc);
3803     return rc;
3804 }
3805 
3806 /*===========================================================================
3807  * FUNCTION   : msgTypeEnabled
3808  *
3809  * DESCRIPTION: impl to determine if certain msg_type is enabled
3810  *
3811  * PARAMETERS :
3812  *   @msg_type  : msg type mask
3813  *
3814  * RETURN     : 0 -- not enabled
3815  *              none 0 -- enabled
3816  *==========================================================================*/
msgTypeEnabled(int32_t msg_type)3817 int QCamera2HardwareInterface::msgTypeEnabled(int32_t msg_type)
3818 {
3819     return (mMsgEnabled & msg_type);
3820 }
3821 
3822 /*===========================================================================
3823  * FUNCTION   : msgTypeEnabledWithLock
3824  *
3825  * DESCRIPTION: impl to determine if certain msg_type is enabled with lock
3826  *
3827  * PARAMETERS :
3828  *   @msg_type  : msg type mask
3829  *
3830  * RETURN     : 0 -- not enabled
3831  *              none 0 -- enabled
3832  *==========================================================================*/
msgTypeEnabledWithLock(int32_t msg_type)3833 int QCamera2HardwareInterface::msgTypeEnabledWithLock(int32_t msg_type)
3834 {
3835     int enabled = 0;
3836     lockAPI();
3837     enabled = mMsgEnabled & msg_type;
3838     unlockAPI();
3839     return enabled;
3840 }
3841 
3842 /*===========================================================================
3843  * FUNCTION   : startPreview
3844  *
3845  * DESCRIPTION: start preview impl
3846  *
3847  * PARAMETERS : none
3848  *
3849  * RETURN     : int32_t type of status
3850  *              NO_ERROR  -- success
3851  *              none-zero failure code
3852  *==========================================================================*/
startPreview()3853 int QCamera2HardwareInterface::startPreview()
3854 {
3855     KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_STARTPREVIEW);
3856     int32_t rc = NO_ERROR;
3857 
3858     LOGI("E ZSL = %d Recording Hint = %d", mParameters.isZSLMode(),
3859             mParameters.getRecordingHintValue());
3860 
3861     m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_START_PREVIEW);
3862 
3863     updateThermalLevel((void *)&mThermalLevel);
3864 
3865     setDisplayFrameSkip();
3866 
3867     // start preview stream
3868     if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) {
3869         rc = startChannel(QCAMERA_CH_TYPE_ZSL);
3870     } else if (isSecureMode()) {
3871         if (mParameters.getSecureStreamType() == CAM_STREAM_TYPE_RAW) {
3872             rc = startChannel(QCAMERA_CH_TYPE_RAW);
3873         }else {
3874             rc = startChannel(QCAMERA_CH_TYPE_PREVIEW);
3875         }
3876     } else {
3877         rc = startChannel(QCAMERA_CH_TYPE_PREVIEW);
3878     }
3879 
3880     if (isDualCamera()) {
3881         if (rc == NO_ERROR) {
3882             mParameters.setDeferCamera(CAM_DEFER_PROCESS);
3883         } else {
3884             mParameters.setDeferCamera(CAM_DEFER_FLUSH);
3885         }
3886     }
3887 
3888     if (rc != NO_ERROR) {
3889         LOGE("failed to start channels");
3890         m_perfLockMgr.releasePerfLock(PERF_LOCK_START_PREVIEW);
3891         return rc;
3892     }
3893 
3894     if ((msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME))
3895             && (m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL)) {
3896         rc = startChannel(QCAMERA_CH_TYPE_CALLBACK);
3897         if (rc != NO_ERROR) {
3898             LOGE("failed to start callback stream");
3899             stopChannel(QCAMERA_CH_TYPE_ZSL);
3900             stopChannel(QCAMERA_CH_TYPE_PREVIEW);
3901             m_perfLockMgr.releasePerfLock(PERF_LOCK_START_PREVIEW);
3902             return rc;
3903         }
3904     }
3905 
3906     updatePostPreviewParameters();
3907     m_stateMachine.setPreviewCallbackNeeded(true);
3908 
3909     // if job id is non-zero, that means the postproc init job is already
3910     // pending or complete
3911     if (mInitPProcJob == 0) {
3912         mInitPProcJob = deferPPInit();
3913         if (mInitPProcJob == 0) {
3914             LOGE("Unable to initialize postprocessor, mCameraHandle = %p",
3915                      mCameraHandle);
3916             rc = -ENOMEM;
3917             m_perfLockMgr.releasePerfLock(PERF_LOCK_START_PREVIEW);
3918             return rc;
3919         }
3920     }
3921 
3922     LOGI("X rc = %d", rc);
3923     return rc;
3924 }
3925 
updatePostPreviewParameters()3926 int32_t QCamera2HardwareInterface::updatePostPreviewParameters() {
3927     // Enable OIS only in Camera mode and 4k2k camcoder mode
3928     int32_t rc = NO_ERROR;
3929     rc = mParameters.updateOisValue(1);
3930     return NO_ERROR;
3931 }
3932 
3933 /*===========================================================================
3934  * FUNCTION   : stopPreview
3935  *
3936  * DESCRIPTION: stop preview impl
3937  *
3938  * PARAMETERS : none
3939  *
3940  * RETURN     : int32_t type of status
3941  *              NO_ERROR  -- success
3942  *              none-zero failure code
3943  *==========================================================================*/
stopPreview()3944 int QCamera2HardwareInterface::stopPreview()
3945 {
3946     KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_STOPPREVIEW);
3947     LOGI("E");
3948     mNumPreviewFaces = -1;
3949     mActiveAF = false;
3950 
3951     // Disable power Hint for preview
3952     m_perfLockMgr.releasePerfLock(PERF_LOCK_POWERHINT_PREVIEW);
3953 
3954     m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_STOP_PREVIEW);
3955 
3956     // stop preview stream
3957     stopChannel(QCAMERA_CH_TYPE_CALLBACK);
3958     stopChannel(QCAMERA_CH_TYPE_ZSL);
3959     stopChannel(QCAMERA_CH_TYPE_PREVIEW);
3960     stopChannel(QCAMERA_CH_TYPE_RAW);
3961 
3962     m_cbNotifier.flushPreviewNotifications();
3963     //add for ts makeup
3964 #ifdef TARGET_TS_MAKEUP
3965     ts_makeup_finish();
3966 #endif
3967     // delete all channels from preparePreview
3968     unpreparePreview();
3969 
3970     m_perfLockMgr.releasePerfLock(PERF_LOCK_STOP_PREVIEW);
3971     LOGI("X");
3972     return NO_ERROR;
3973 }
3974 
3975 /*===========================================================================
3976  * FUNCTION   : storeMetaDataInBuffers
3977  *
3978  * DESCRIPTION: enable store meta data in buffers for video frames impl
3979  *
3980  * PARAMETERS :
3981  *   @enable  : flag if need enable
3982  *
3983  * RETURN     : int32_t type of status
3984  *              NO_ERROR  -- success
3985  *              none-zero failure code
3986  *==========================================================================*/
storeMetaDataInBuffers(int enable)3987 int QCamera2HardwareInterface::storeMetaDataInBuffers(int enable)
3988 {
3989     mStoreMetaDataInFrame = enable;
3990     return NO_ERROR;
3991 }
3992 
3993 /*===========================================================================
3994  * FUNCTION   : preStartRecording
3995  *
3996  * DESCRIPTION: Prepare start recording impl
3997  *
3998  * PARAMETERS : none
3999  *
4000  * RETURN     : int32_t type of status
4001  *              NO_ERROR  -- success
4002  *              none-zero failure code
4003  *==========================================================================*/
preStartRecording()4004 int QCamera2HardwareInterface::preStartRecording()
4005 {
4006     int32_t rc = NO_ERROR;
4007     LOGH("E");
4008     if (mParameters.getRecordingHintValue() == false) {
4009 
4010         // Give HWI control to restart preview only in single camera mode.
4011         // In dual-cam mode, this control belongs to muxer.
4012         if (getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
4013             LOGH("start recording when hint is false, stop preview first");
4014             stopPreview();
4015 
4016             // Set recording hint to TRUE
4017             mParameters.updateRecordingHintValue(TRUE);
4018             rc = preparePreview();
4019             if (rc == NO_ERROR) {
4020                 rc = startPreview();
4021             }
4022         }
4023         else
4024         {
4025             // For dual cam mode, update the flag mPreviewRestartNeeded to true
4026             // Restart control will be handled by muxer.
4027             mPreviewRestartNeeded = true;
4028         }
4029     }
4030 
4031     LOGH("X rc = %d", rc);
4032     return rc;
4033 }
4034 
4035 /*===========================================================================
4036  * FUNCTION   : startRecording
4037  *
4038  * DESCRIPTION: start recording impl
4039  *
4040  * PARAMETERS : none
4041  *
4042  * RETURN     : int32_t type of status
4043  *              NO_ERROR  -- success
4044  *              none-zero failure code
4045  *==========================================================================*/
startRecording()4046 int QCamera2HardwareInterface::startRecording()
4047 {
4048     int32_t rc = NO_ERROR;
4049 
4050     LOGI("E");
4051 
4052     m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_START_RECORDING);
4053 
4054     //link meta stream with video channel if low power mode.
4055     if (isLowPowerMode()) {
4056         // Find and try to link a metadata stream from preview channel
4057         QCameraChannel *pMetaChannel = NULL;
4058         QCameraStream *pMetaStream = NULL;
4059         QCameraChannel *pVideoChannel = m_channels[QCAMERA_CH_TYPE_VIDEO];
4060 
4061         if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
4062             pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
4063             uint32_t streamNum = pMetaChannel->getNumOfStreams();
4064             QCameraStream *pStream = NULL;
4065             for (uint32_t i = 0 ; i < streamNum ; i++ ) {
4066                 pStream = pMetaChannel->getStreamByIndex(i);
4067                 if ((NULL != pStream) &&
4068                         (CAM_STREAM_TYPE_METADATA == pStream->getMyType())) {
4069                     pMetaStream = pStream;
4070                     break;
4071                 }
4072             }
4073         }
4074 
4075         if ((NULL != pMetaChannel) && (NULL != pMetaStream)) {
4076             rc = pVideoChannel->linkStream(pMetaChannel, pMetaStream);
4077             if (NO_ERROR != rc) {
4078                 LOGW("Metadata stream link failed %d", rc);
4079             }
4080         }
4081     }
4082 
4083     if (rc == NO_ERROR) {
4084         rc = startChannel(QCAMERA_CH_TYPE_VIDEO);
4085     }
4086 
4087     if (mParameters.isTNRSnapshotEnabled() && !isLowPowerMode()) {
4088         QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
4089         if (!mParameters.is4k2kVideoResolution()) {
4090             // Find and try to link a metadata stream from preview channel
4091             QCameraChannel *pMetaChannel = NULL;
4092             QCameraStream *pMetaStream = NULL;
4093 
4094             if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
4095                 pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
4096                 uint32_t streamNum = pMetaChannel->getNumOfStreams();
4097                 QCameraStream *pStream = NULL;
4098                 for (uint32_t i = 0 ; i < streamNum ; i++ ) {
4099                     pStream = pMetaChannel->getStreamByIndex(i);
4100                     if ((NULL != pStream) &&
4101                             (CAM_STREAM_TYPE_METADATA ==
4102                             pStream->getMyType())) {
4103                         pMetaStream = pStream;
4104                         break;
4105                     }
4106                 }
4107             }
4108 
4109             if ((NULL != pMetaChannel) && (NULL != pMetaStream)) {
4110                 rc = pChannel->linkStream(pMetaChannel, pMetaStream);
4111                 if (NO_ERROR != rc) {
4112                     LOGW("Metadata stream link failed %d", rc);
4113                 }
4114             }
4115         }
4116         LOGH("START snapshot Channel for TNR processing");
4117         rc = pChannel->start();
4118     }
4119 
4120     m_perfLockMgr.releasePerfLock(PERF_LOCK_START_RECORDING);
4121 
4122     if (rc == NO_ERROR) {
4123         // Set power Hint for video encoding
4124         m_perfLockMgr.acquirePerfLock(PERF_LOCK_POWERHINT_ENCODE, 0);
4125     }
4126 
4127     LOGI("X rc = %d", rc);
4128     return rc;
4129 }
4130 
4131 /*===========================================================================
4132  * FUNCTION   : stopRecording
4133  *
4134  * DESCRIPTION: stop recording impl
4135  *
4136  * PARAMETERS : none
4137  *
4138  * RETURN     : int32_t type of status
4139  *              NO_ERROR  -- success
4140  *              none-zero failure code
4141  *==========================================================================*/
stopRecording()4142 int QCamera2HardwareInterface::stopRecording()
4143 {
4144     LOGI("E");
4145 
4146     // Disable power hint for video encoding
4147     m_perfLockMgr.releasePerfLock(PERF_LOCK_POWERHINT_ENCODE);
4148 
4149     m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_STOP_RECORDING);
4150 
4151     // stop snapshot channel
4152     if (mParameters.isTNRSnapshotEnabled()) {
4153         LOGH("STOP snapshot Channel for TNR processing");
4154         stopChannel(QCAMERA_CH_TYPE_SNAPSHOT);
4155     }
4156     int rc = stopChannel(QCAMERA_CH_TYPE_VIDEO);
4157 
4158     m_cbNotifier.flushVideoNotifications();
4159 
4160     m_perfLockMgr.releasePerfLock(PERF_LOCK_STOP_RECORDING);
4161 
4162     LOGI("X rc = %d", rc);
4163     return rc;
4164 }
4165 
4166 /*===========================================================================
4167  * FUNCTION   : releaseRecordingFrame
4168  *
4169  * DESCRIPTION: return video frame impl
4170  *
4171  * PARAMETERS :
4172  *   @opaque  : ptr to video frame to be returned
4173  *
4174  * RETURN     : int32_t type of status
4175  *              NO_ERROR  -- success
4176  *              none-zero failure code
4177  *==========================================================================*/
releaseRecordingFrame(const void * opaque)4178 int QCamera2HardwareInterface::releaseRecordingFrame(const void * opaque)
4179 {
4180     int32_t rc = UNKNOWN_ERROR;
4181     QCameraVideoChannel *pChannel =
4182             (QCameraVideoChannel *)m_channels[QCAMERA_CH_TYPE_VIDEO];
4183     LOGD("opaque data = %p",opaque);
4184 
4185     if(pChannel != NULL) {
4186         rc = pChannel->releaseFrame(opaque, mStoreMetaDataInFrame > 0);
4187     }
4188     return rc;
4189 }
4190 
4191 /*===========================================================================
4192  * FUNCTION   : autoFocus
4193  *
4194  * DESCRIPTION: start auto focus impl
4195  *
4196  * PARAMETERS : none
4197  *
4198  * RETURN     : int32_t type of status
4199  *              NO_ERROR  -- success
4200  *              none-zero failure code
4201  *==========================================================================*/
autoFocus()4202 int QCamera2HardwareInterface::autoFocus()
4203 {
4204     int rc = NO_ERROR;
4205     cam_focus_mode_type focusMode = mParameters.getFocusMode();
4206     LOGH("E");
4207 
4208     switch (focusMode) {
4209     case CAM_FOCUS_MODE_AUTO:
4210     case CAM_FOCUS_MODE_MACRO:
4211     case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
4212     case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
4213         mActiveAF = true;
4214         LOGI("Send AUTO FOCUS event. focusMode=%d, m_currentFocusState=%d",
4215                 focusMode, m_currentFocusState);
4216         rc = mCameraHandle->ops->do_auto_focus(mCameraHandle->camera_handle);
4217         break;
4218     case CAM_FOCUS_MODE_INFINITY:
4219     case CAM_FOCUS_MODE_FIXED:
4220     case CAM_FOCUS_MODE_EDOF:
4221     default:
4222         LOGI("No ops in focusMode (%d)", focusMode);
4223         rc = sendEvtNotify(CAMERA_MSG_FOCUS, true, 0);
4224         break;
4225     }
4226 
4227     if (NO_ERROR != rc) {
4228         mActiveAF = false;
4229     }
4230     LOGH("X rc = %d", rc);
4231     return rc;
4232 }
4233 
4234 /*===========================================================================
4235  * FUNCTION   : cancelAutoFocus
4236  *
4237  * DESCRIPTION: cancel auto focus impl
4238  *
4239  * PARAMETERS : none
4240  *
4241  * RETURN     : int32_t type of status
4242  *              NO_ERROR  -- success
4243  *              none-zero failure code
4244  *==========================================================================*/
cancelAutoFocus()4245 int QCamera2HardwareInterface::cancelAutoFocus()
4246 {
4247     int rc = NO_ERROR;
4248     cam_focus_mode_type focusMode = mParameters.getFocusMode();
4249 
4250     switch (focusMode) {
4251     case CAM_FOCUS_MODE_AUTO:
4252     case CAM_FOCUS_MODE_MACRO:
4253     case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
4254     case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
4255         mActiveAF = false;
4256         rc = mCameraHandle->ops->cancel_auto_focus(mCameraHandle->camera_handle);
4257         break;
4258     case CAM_FOCUS_MODE_INFINITY:
4259     case CAM_FOCUS_MODE_FIXED:
4260     case CAM_FOCUS_MODE_EDOF:
4261     default:
4262         LOGD("No ops in focusMode (%d)", focusMode);
4263         break;
4264     }
4265     return rc;
4266 }
4267 
4268 /*===========================================================================
4269  * FUNCTION   : processUFDumps
4270  *
4271  * DESCRIPTION: process UF jpeg dumps for refocus support
4272  *
4273  * PARAMETERS :
4274  *   @evt     : payload of jpeg event, including information about jpeg encoding
4275  *              status, jpeg size and so on.
4276  *
4277  * RETURN     : int32_t type of status
4278  *              NO_ERROR  -- success
4279  *              none-zero failure code
4280  *
4281  * NOTE       : none
4282  *==========================================================================*/
processUFDumps(qcamera_jpeg_evt_payload_t * evt)4283 bool QCamera2HardwareInterface::processUFDumps(qcamera_jpeg_evt_payload_t *evt)
4284 {
4285    bool ret = true;
4286    if (mParameters.isUbiRefocus()) {
4287        int index = (int)getOutputImageCount();
4288        bool allFocusImage = (index == ((int)mParameters.getRefocusOutputCount() - 1));
4289        char name[FILENAME_MAX];
4290 
4291        camera_memory_t *jpeg_mem = NULL;
4292        omx_jpeg_ouput_buf_t *jpeg_out = NULL;
4293        size_t dataLen;
4294        uint8_t *dataPtr;
4295        if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
4296            LOGE("Init PProc Deferred work failed");
4297            return false;
4298        }
4299        if (!m_postprocessor.getJpegMemOpt()) {
4300            dataLen = evt->out_data.buf_filled_len;
4301            dataPtr = evt->out_data.buf_vaddr;
4302        } else {
4303            jpeg_out  = (omx_jpeg_ouput_buf_t*) evt->out_data.buf_vaddr;
4304            if (!jpeg_out) {
4305               LOGE("Null pointer detected");
4306               return false;
4307            }
4308            jpeg_mem = (camera_memory_t *)jpeg_out->mem_hdl;
4309            if (!jpeg_mem) {
4310               LOGE("Null pointer detected");
4311               return false;
4312            }
4313            dataPtr = (uint8_t *)jpeg_mem->data;
4314            dataLen = jpeg_mem->size;
4315        }
4316 
4317        if (allFocusImage)  {
4318            snprintf(name, sizeof(name), "AllFocusImage");
4319            index = -1;
4320        } else {
4321            snprintf(name, sizeof(name), "%d", 0);
4322        }
4323        CAM_DUMP_TO_FILE(QCAMERA_DUMP_FRM_LOCATION"ubifocus", name, index, "jpg",
4324            dataPtr, dataLen);
4325        LOGD("Dump the image %d %d allFocusImage %d",
4326            getOutputImageCount(), index, allFocusImage);
4327        setOutputImageCount(getOutputImageCount() + 1);
4328        if (!allFocusImage) {
4329            ret = false;
4330        }
4331    }
4332    return ret;
4333 }
4334 
4335 /*===========================================================================
4336  * FUNCTION   : unconfigureAdvancedCapture
4337  *
4338  * DESCRIPTION: unconfigure Advanced Capture.
4339  *
4340  * PARAMETERS : none
4341  *
4342  * RETURN     : int32_t type of status
4343  *              NO_ERROR  -- success
4344  *              none-zero failure code
4345  *==========================================================================*/
unconfigureAdvancedCapture()4346 int32_t QCamera2HardwareInterface::unconfigureAdvancedCapture()
4347 {
4348     int32_t rc = NO_ERROR;
4349 
4350     /*Disable Quadra CFA mode*/
4351     LOGH("Disabling Quadra CFA mode");
4352     mParameters.setQuadraCfaMode(false, true);
4353 
4354     if (mAdvancedCaptureConfigured) {
4355 
4356         mAdvancedCaptureConfigured = false;
4357 
4358         if(mIs3ALocked) {
4359             mParameters.set3ALock(false);
4360             mIs3ALocked = false;
4361         }
4362         if (mParameters.isHDREnabled() || mParameters.isAEBracketEnabled()) {
4363             rc = mParameters.setToneMapMode(true, true);
4364             if (rc != NO_ERROR) {
4365                 LOGW("Failed to enable tone map during HDR/AEBracketing");
4366             }
4367             mHDRBracketingEnabled = false;
4368             rc = mParameters.stopAEBracket();
4369         } else if ((mParameters.isChromaFlashEnabled())
4370                 || (mFlashConfigured && !mLongshotEnabled)
4371                 || (mLowLightConfigured == true)
4372                 || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
4373             rc = mParameters.resetFrameCapture(TRUE, mLowLightConfigured);
4374         } else if (mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
4375             rc = configureAFBracketing(false);
4376         } else if (mParameters.isOptiZoomEnabled()) {
4377             rc = mParameters.setAndCommitZoom(mZoomLevel);
4378             setDisplaySkip(FALSE, CAMERA_MAX_PARAM_APPLY_DELAY);
4379         } else if (mParameters.isStillMoreEnabled()) {
4380             cam_still_more_t stillmore_config = mParameters.getStillMoreSettings();
4381             stillmore_config.burst_count = 0;
4382             mParameters.setStillMoreSettings(stillmore_config);
4383 
4384             /* If SeeMore is running, it will handle re-enabling tone map */
4385             if (!mParameters.isSeeMoreEnabled() && !mParameters.isLTMForSeeMoreEnabled()) {
4386                 rc = mParameters.setToneMapMode(true, true);
4387                 if (rc != NO_ERROR) {
4388                     LOGW("Failed to enable tone map during StillMore");
4389                 }
4390             }
4391 
4392             /* Re-enable Tintless */
4393             mParameters.setTintless(true);
4394         } else {
4395             LOGW("No Advanced Capture feature enabled!!");
4396             rc = BAD_VALUE;
4397         }
4398     }
4399 
4400     return rc;
4401 }
4402 
4403 /*===========================================================================
4404  * FUNCTION   : configureAdvancedCapture
4405  *
4406  * DESCRIPTION: configure Advanced Capture.
4407  *
4408  * PARAMETERS : none
4409  *
4410  * RETURN     : int32_t type of status
4411  *              NO_ERROR  -- success
4412  *              none-zero failure code
4413  *==========================================================================*/
configureAdvancedCapture()4414 int32_t QCamera2HardwareInterface::configureAdvancedCapture()
4415 {
4416     LOGH("E");
4417     int32_t rc = NO_ERROR;
4418 
4419     rc = mParameters.checkFeatureConcurrency();
4420     if (rc != NO_ERROR) {
4421         LOGE("Cannot support Advanced capture modes");
4422         return rc;
4423     }
4424     /*Enable Quadra CFA mode*/
4425     LOGH("Enabling Quadra CFA mode");
4426     mParameters.setQuadraCfaMode(true, true);
4427 
4428     setOutputImageCount(0);
4429     mInputCount = 0;
4430     mAdvancedCaptureConfigured = true;
4431     /* Display should be disabled for advanced modes */
4432     bool bSkipDisplay = true;
4433 
4434     if (getRelatedCamSyncInfo()->mode == CAM_MODE_SECONDARY) {
4435         // no Advance capture settings for Aux camera
4436         LOGH("X Secondary Camera, no need to process!! ");
4437         return rc;
4438     }
4439 
4440     /* Do not stop display if in stillmore livesnapshot */
4441     if (mParameters.isStillMoreEnabled() &&
4442             mParameters.isSeeMoreEnabled()) {
4443         bSkipDisplay = false;
4444     }
4445     if (mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
4446         rc = configureAFBracketing();
4447     } else if (mParameters.isOptiZoomEnabled()) {
4448         rc = configureOptiZoom();
4449     } else if(mParameters.isHDREnabled()) {
4450         rc = configureHDRBracketing();
4451         if (mHDRBracketingEnabled) {
4452             rc = mParameters.setToneMapMode(false, true);
4453             if (rc != NO_ERROR) {
4454                 LOGW("Failed to disable tone map during HDR");
4455             }
4456         }
4457     } else if (mParameters.isAEBracketEnabled()) {
4458         rc = mParameters.setToneMapMode(false, true);
4459         if (rc != NO_ERROR) {
4460             LOGW("Failed to disable tone map during AEBracketing");
4461         }
4462         rc = configureAEBracketing();
4463     } else if (mParameters.isStillMoreEnabled()) {
4464         bSkipDisplay = false;
4465         rc = configureStillMore();
4466     } else if ((mParameters.isChromaFlashEnabled())
4467             || (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF)
4468             || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
4469         rc = mParameters.configFrameCapture(TRUE);
4470         if (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF) {
4471             mLowLightConfigured = true;
4472         }
4473     } else if (mFlashNeeded && !mLongshotEnabled) {
4474         rc = mParameters.configFrameCapture(TRUE);
4475         mFlashConfigured = true;
4476         bSkipDisplay = false;
4477     } else {
4478         LOGH("Advanced Capture feature not enabled!! ");
4479         mAdvancedCaptureConfigured = false;
4480         bSkipDisplay = false;
4481     }
4482 
4483     if (m_postprocessor.isHalPPEnabled()) {
4484         LOGH("HALPP is enabled, check if halpp is needed for current snapshot.");
4485         configureHalPostProcess();
4486     }
4487 
4488     LOGH("Stop preview temporarily for advanced captures");
4489     setDisplaySkip(bSkipDisplay);
4490 
4491     LOGH("X rc = %d", rc);
4492     return rc;
4493 }
4494 
4495 /*===========================================================================
4496  * FUNCTION   : configureAFBracketing
4497  *
4498  * DESCRIPTION: configure AF Bracketing.
4499  *
4500  * PARAMETERS : none
4501  *
4502  * RETURN     : int32_t type of status
4503  *              NO_ERROR  -- success
4504  *              none-zero failure code
4505  *==========================================================================*/
configureAFBracketing(bool enable)4506 int32_t QCamera2HardwareInterface::configureAFBracketing(bool enable)
4507 {
4508     LOGH("E");
4509     int32_t rc = NO_ERROR;
4510     cam_af_bracketing_t *af_bracketing_need;
4511 
4512     if (mParameters.isUbiRefocus()) {
4513         af_bracketing_need =
4514                 &gCamCapability[mCameraId]->refocus_af_bracketing_need;
4515     } else {
4516         af_bracketing_need =
4517                 &gCamCapability[mCameraId]->ubifocus_af_bracketing_need;
4518     }
4519 
4520     //Enable AF Bracketing.
4521     cam_af_bracketing_t afBracket;
4522     memset(&afBracket, 0, sizeof(cam_af_bracketing_t));
4523     afBracket.enable = enable;
4524     afBracket.burst_count = af_bracketing_need->burst_count;
4525 
4526     for(int8_t i = 0; i < MAX_AF_BRACKETING_VALUES; i++) {
4527         afBracket.focus_steps[i] = af_bracketing_need->focus_steps[i];
4528         LOGH("focus_step[%d] = %d", i, afBracket.focus_steps[i]);
4529     }
4530     //Send cmd to backend to set AF Bracketing for Ubi Focus.
4531     rc = mParameters.commitAFBracket(afBracket);
4532     if ( NO_ERROR != rc ) {
4533         LOGE("cannot configure AF bracketing");
4534         return rc;
4535     }
4536     if (enable) {
4537         mParameters.set3ALock(true);
4538         mIs3ALocked = true;
4539     }
4540     LOGH("X rc = %d", rc);
4541     return rc;
4542 }
4543 
4544 /*===========================================================================
4545  * FUNCTION   : configureHDRBracketing
4546  *
4547  * DESCRIPTION: configure HDR Bracketing.
4548  *
4549  * PARAMETERS : none
4550  *
4551  * RETURN     : int32_t type of status
4552  *              NO_ERROR  -- success
4553  *              none-zero failure code
4554  *==========================================================================*/
configureHDRBracketing()4555 int32_t QCamera2HardwareInterface::configureHDRBracketing()
4556 {
4557     LOGH("E");
4558     int32_t rc = NO_ERROR;
4559 
4560     cam_hdr_bracketing_info_t& hdrBracketingSetting =
4561             gCamCapability[mCameraId]->hdr_bracketing_setting;
4562 
4563     // 'values' should be in "idx1,idx2,idx3,..." format
4564     uint32_t hdrFrameCount =
4565             hdrBracketingSetting.num_frames;
4566     LOGH("HDR values %d, %d frame count: %u",
4567           (int8_t) hdrBracketingSetting.exp_val.values[0],
4568           (int8_t) hdrBracketingSetting.exp_val.values[1],
4569           hdrFrameCount);
4570 
4571     // Enable AE Bracketing for HDR
4572     cam_exp_bracketing_t aeBracket;
4573     memset(&aeBracket, 0, sizeof(cam_exp_bracketing_t));
4574     aeBracket.mode =
4575         hdrBracketingSetting.exp_val.mode;
4576 
4577     if (aeBracket.mode == CAM_EXP_BRACKETING_ON) {
4578         mHDRBracketingEnabled = true;
4579     }
4580 
4581     String8 tmp;
4582     for (uint32_t i = 0; i < hdrFrameCount; i++) {
4583         tmp.appendFormat("%d",
4584             (int8_t) hdrBracketingSetting.exp_val.values[i]);
4585         tmp.append(",");
4586     }
4587     if (mParameters.isHDR1xFrameEnabled()
4588         && mParameters.isHDR1xExtraBufferNeeded()) {
4589             tmp.appendFormat("%d", 0);
4590             tmp.append(",");
4591     }
4592 
4593     if( !tmp.isEmpty() &&
4594         ( MAX_EXP_BRACKETING_LENGTH > tmp.length() ) ) {
4595         //Trim last comma
4596         memset(aeBracket.values, '\0', MAX_EXP_BRACKETING_LENGTH);
4597         memcpy(aeBracket.values, tmp.string(), tmp.length() - 1);
4598     }
4599 
4600     LOGH("HDR config values %s",
4601           aeBracket.values);
4602     rc = mParameters.setHDRAEBracket(aeBracket);
4603     if ( NO_ERROR != rc ) {
4604         LOGE("cannot configure HDR bracketing");
4605         return rc;
4606     }
4607     LOGH("X rc = %d", rc);
4608     return rc;
4609 }
4610 
4611 /*===========================================================================
4612  * FUNCTION   : configureAEBracketing
4613  *
4614  * DESCRIPTION: configure AE Bracketing.
4615  *
4616  * PARAMETERS : none
4617  *
4618  * RETURN     : int32_t type of status
4619  *              NO_ERROR  -- success
4620  *              none-zero failure code
4621  *==========================================================================*/
configureAEBracketing()4622 int32_t QCamera2HardwareInterface::configureAEBracketing()
4623 {
4624     LOGH("E");
4625     int32_t rc = NO_ERROR;
4626 
4627     rc = mParameters.setAEBracketing();
4628     if ( NO_ERROR != rc ) {
4629         LOGE("cannot configure AE bracketing");
4630         return rc;
4631     }
4632     LOGH("X rc = %d", rc);
4633     return rc;
4634 }
4635 
4636 /*===========================================================================
4637  * FUNCTION   : configureOptiZoom
4638  *
4639  * DESCRIPTION: configure Opti Zoom.
4640  *
4641  * PARAMETERS : none
4642  *
4643  * RETURN     : int32_t type of status
4644  *              NO_ERROR  -- success
4645  *              none-zero failure code
4646  *==========================================================================*/
configureOptiZoom()4647 int32_t QCamera2HardwareInterface::configureOptiZoom()
4648 {
4649     int32_t rc = NO_ERROR;
4650 
4651     //store current zoom level.
4652     mZoomLevel = mParameters.getParmZoomLevel();
4653 
4654     //set zoom level to 1x;
4655     mParameters.setAndCommitZoom(0);
4656 
4657     mParameters.set3ALock(true);
4658     mIs3ALocked = true;
4659 
4660     return rc;
4661 }
4662 
4663 /*===========================================================================
4664  * FUNCTION   : configureStillMore
4665  *
4666  * DESCRIPTION: configure StillMore.
4667  *
4668  * PARAMETERS : none
4669  *
4670  * RETURN     : int32_t type of status
4671  *              NO_ERROR  -- success
4672  *              none-zero failure code
4673  *==========================================================================*/
configureStillMore()4674 int32_t QCamera2HardwareInterface::configureStillMore()
4675 {
4676     int32_t rc = NO_ERROR;
4677     uint8_t burst_cnt = 0;
4678     cam_still_more_t stillmore_config;
4679     cam_still_more_t stillmore_cap;
4680 
4681     /* Disable Tone Map. If seemore is enabled, it will handle disabling it. */
4682     if (!mParameters.isSeeMoreEnabled() && !mParameters.isLTMForSeeMoreEnabled()) {
4683         rc = mParameters.setToneMapMode(false, true);
4684         if (rc != NO_ERROR) {
4685             LOGW("Failed to disable tone map during StillMore");
4686         }
4687     }
4688 
4689     /* Lock 3A */
4690     mParameters.set3ALock(true);
4691     mIs3ALocked = true;
4692 
4693     /* Disable Tintless */
4694     mParameters.setTintless(false);
4695 
4696     /* Initialize burst count from capability */
4697     stillmore_cap = mParameters.getStillMoreCapability();
4698     burst_cnt = stillmore_cap.max_burst_count;
4699 
4700     /* Reconfigure burst count from dynamic scene data */
4701     cam_dyn_img_data_t dynamic_img_data = mParameters.getDynamicImgData();
4702     if (dynamic_img_data.input_count >= stillmore_cap.min_burst_count &&
4703             dynamic_img_data.input_count <= stillmore_cap.max_burst_count) {
4704         burst_cnt = dynamic_img_data.input_count;
4705     }
4706 
4707     /* Reconfigure burst count in the case of liveshot */
4708     if (mParameters.isSeeMoreEnabled()) {
4709         burst_cnt = 1;
4710     }
4711 
4712     /* Reconfigure burst count from user input */
4713     char prop[PROPERTY_VALUE_MAX];
4714     property_get("persist.camera.imglib.stillmore", prop, "0");
4715     uint8_t burst_setprop = (uint32_t)atoi(prop);
4716     if (burst_setprop != 0)  {
4717        if ((burst_setprop < stillmore_cap.min_burst_count) ||
4718                (burst_setprop > stillmore_cap.max_burst_count)) {
4719            burst_cnt = stillmore_cap.max_burst_count;
4720        } else {
4721            burst_cnt = burst_setprop;
4722        }
4723     }
4724 
4725     memset(&stillmore_config, 0, sizeof(cam_still_more_t));
4726     stillmore_config.burst_count = burst_cnt;
4727     mParameters.setStillMoreSettings(stillmore_config);
4728 
4729     LOGH("Stillmore burst %d", burst_cnt);
4730 
4731     return rc;
4732 }
4733 
4734 /*===========================================================================
4735  * FUNCTION   : configureHalPostProcess
4736  *
4737  * DESCRIPTION: config hal postproc (HALPP) for current snapshot.
4738  *
4739  * PARAMETERS : none
4740  *
4741  * RETURN     : int32_t type of status
4742  *              NO_ERROR  -- success
4743  *              none-zero failure code
4744  *==========================================================================*/
configureHalPostProcess()4745 int32_t QCamera2HardwareInterface::configureHalPostProcess()
4746 {
4747     LOGD("E");
4748     int32_t rc = NO_ERROR;
4749 
4750     if (!m_postprocessor.isHalPPEnabled()) {
4751         m_bNeedHalPP = FALSE;
4752         return rc;
4753     }
4754 
4755     /* check if halpp is needed in dual camera mode */
4756     if (isDualCamera()) {
4757         if (mActiveCameras == MM_CAMERA_DUAL_CAM && mBundledSnapshot == TRUE) {
4758             LOGH("Use HALPP for dual camera bundle snapshot.");
4759             m_bNeedHalPP = TRUE;
4760         }
4761         return rc;
4762     }
4763 
4764     return rc;
4765     LOGD("X");
4766 }
4767 
4768 
4769 /*===========================================================================
4770  * FUNCTION   : stopAdvancedCapture
4771  *
4772  * DESCRIPTION: stops advanced capture based on capture type
4773  *
4774  * PARAMETERS :
4775  *   @pChannel : channel.
4776  *
4777  * RETURN     : int32_t type of status
4778  *              NO_ERROR  -- success
4779  *              none-zero failure code
4780  *==========================================================================*/
stopAdvancedCapture(QCameraPicChannel * pChannel)4781 int32_t QCamera2HardwareInterface::stopAdvancedCapture(
4782         QCameraPicChannel *pChannel)
4783 {
4784     LOGH("stop bracketig");
4785     int32_t rc = NO_ERROR;
4786 
4787     if(mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
4788         rc = pChannel->stopAdvancedCapture(MM_CAMERA_AF_BRACKETING);
4789     } else if (mParameters.isChromaFlashEnabled()
4790             || (mFlashConfigured && !mLongshotEnabled)
4791             || (mLowLightConfigured == true)
4792             || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
4793         rc = pChannel->stopAdvancedCapture(MM_CAMERA_FRAME_CAPTURE);
4794         mFlashConfigured = false;
4795         mLowLightConfigured = false;
4796     } else if(mParameters.isHDREnabled()
4797             || mParameters.isAEBracketEnabled()) {
4798         rc = pChannel->stopAdvancedCapture(MM_CAMERA_AE_BRACKETING);
4799     } else if (mParameters.isOptiZoomEnabled()) {
4800         rc = pChannel->stopAdvancedCapture(MM_CAMERA_ZOOM_1X);
4801     } else if (mParameters.isStillMoreEnabled()) {
4802         LOGH("stopAdvancedCapture not needed for StillMore");
4803     } else {
4804         LOGH("No Advanced Capture feature enabled!");
4805         rc = BAD_VALUE;
4806     }
4807 
4808     m_bNeedHalPP = FALSE;
4809     return rc;
4810 }
4811 
4812 /*===========================================================================
4813  * FUNCTION   : startAdvancedCapture
4814  *
4815  * DESCRIPTION: starts advanced capture based on capture type
4816  *
4817  * PARAMETERS :
4818  *   @pChannel : channel.
4819  *
4820  * RETURN     : int32_t type of status
4821  *              NO_ERROR  -- success
4822  *              none-zero failure code
4823  *==========================================================================*/
startAdvancedCapture(QCameraPicChannel * pChannel)4824 int32_t QCamera2HardwareInterface::startAdvancedCapture(
4825         QCameraPicChannel *pChannel)
4826 {
4827     LOGH("Start bracketing");
4828     int32_t rc = NO_ERROR;
4829 
4830     if(mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
4831         rc = pChannel->startAdvancedCapture(MM_CAMERA_AF_BRACKETING);
4832     } else if (mParameters.isOptiZoomEnabled()) {
4833         rc = pChannel->startAdvancedCapture(MM_CAMERA_ZOOM_1X);
4834     } else if (mParameters.isStillMoreEnabled()) {
4835         LOGH("startAdvancedCapture not needed for StillMore");
4836     } else if (mParameters.isHDREnabled()
4837             || mParameters.isAEBracketEnabled()) {
4838         rc = pChannel->startAdvancedCapture(MM_CAMERA_AE_BRACKETING);
4839     } else if (mParameters.isChromaFlashEnabled()
4840             || (mFlashNeeded && !mLongshotEnabled)
4841             || (mLowLightConfigured == true)
4842             || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
4843         cam_capture_frame_config_t config = mParameters.getCaptureFrameConfig();
4844         rc = pChannel->startAdvancedCapture(MM_CAMERA_FRAME_CAPTURE, &config);
4845     } else {
4846         LOGE("No Advanced Capture feature enabled!");
4847         rc = BAD_VALUE;
4848     }
4849     return rc;
4850 }
4851 
4852 /*===========================================================================
4853  * FUNCTION   : preTakePicture
4854  *
4855  * DESCRIPTION: Prepare take picture impl, Restarts preview if necessary
4856  *
4857  * PARAMETERS : none
4858  *
4859  * RETURN     : int32_t type of status
4860  *              NO_ERROR  -- success
4861  *              none-zero failure code
4862  *==========================================================================*/
preTakePicture()4863 int QCamera2HardwareInterface::preTakePicture()
4864 {
4865     int32_t rc = NO_ERROR;
4866     LOGH("E");
4867     if (mParameters.getRecordingHintValue() == true) {
4868 
4869         // Give HWI control to restart preview only in single camera mode.
4870         // In dual-cam mode, this control belongs to muxer.
4871         if (getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
4872             LOGH("restart preview if rec hint is true and preview is running");
4873             stopPreview();
4874             mParameters.updateRecordingHintValue(FALSE);
4875             // start preview again
4876             rc = preparePreview();
4877             if (rc == NO_ERROR) {
4878                 rc = startPreview();
4879                 if (rc != NO_ERROR) {
4880                     unpreparePreview();
4881                 }
4882             }
4883         }
4884         else
4885         {
4886             // For dual cam mode, update the flag mPreviewRestartNeeded to true
4887             // Restart control will be handled by muxer.
4888             mPreviewRestartNeeded = true;
4889         }
4890     }
4891 
4892     LOGH("X rc = %d", rc);
4893     return rc;
4894 }
4895 
4896 /*===========================================================================
4897  * FUNCTION   : takePicture
4898  *
4899  * DESCRIPTION: take picture impl
4900  *
4901  * PARAMETERS : none
4902  *
4903  * RETURN     : int32_t type of status
4904  *              NO_ERROR  -- success
4905  *              none-zero failure code
4906  *==========================================================================*/
takePicture()4907 int QCamera2HardwareInterface::takePicture()
4908 {
4909     int rc = NO_ERROR;
4910 
4911     // Get total number for snapshots (retro + regular)
4912     uint8_t numSnapshots = mParameters.getNumOfSnapshots();
4913     // Get number of retro-active snapshots
4914     uint8_t numRetroSnapshots = mParameters.getNumOfRetroSnapshots();
4915     LOGH("E");
4916 
4917     //Set rotation value from user settings as Jpeg rotation
4918     //to configure back-end modules.
4919     mParameters.setJpegRotation(mParameters.getRotation());
4920 
4921     // Check if retro-active snapshots are not enabled
4922     if (!isRetroPicture() || !mParameters.isZSLMode()) {
4923       numRetroSnapshots = 0;
4924       LOGH("Reset retro snaphot count to zero");
4925     }
4926 
4927     //Do special configure for advanced capture modes.
4928     rc = configureAdvancedCapture();
4929     if (rc != NO_ERROR) {
4930         LOGE("Unsupported capture call");
4931         return rc;
4932     }
4933 
4934     if (mAdvancedCaptureConfigured) {
4935         numSnapshots = mParameters.getBurstCountForAdvancedCapture();
4936     }
4937 
4938     if (mActiveCameras == MM_CAMERA_DUAL_CAM && mBundledSnapshot) {
4939         char prop[PROPERTY_VALUE_MAX];
4940         memset(prop, 0, sizeof(prop));
4941         property_get("persist.camera.dualfov.jpegnum", prop, "1");
4942         int dualfov_snap_num = atoi(prop);
4943 
4944         memset(prop, 0, sizeof(prop));
4945         property_get("persist.camera.halpp", prop, "0");
4946         int halpp_enabled = atoi(prop);
4947         if(halpp_enabled == 0) {
4948             dualfov_snap_num = MM_CAMERA_MAX_CAM_CNT;
4949         }
4950 
4951         dualfov_snap_num = (dualfov_snap_num == 0) ? 1 : dualfov_snap_num;
4952         LOGD("dualfov_snap_num:%d", dualfov_snap_num);
4953         numSnapshots /= dualfov_snap_num;
4954     }
4955 
4956     LOGI("snap count = %d zsl = %d advanced = %d, active camera:%d",
4957             numSnapshots, mParameters.isZSLMode(), mAdvancedCaptureConfigured, mActiveCameras);
4958 
4959     if (mParameters.isZSLMode()) {
4960         QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
4961         QCameraPicChannel *pPicChannel = (QCameraPicChannel *)pChannel;
4962         if (NULL != pPicChannel) {
4963 
4964             if (mParameters.getofflineRAW()) {
4965                 startRAWChannel(pPicChannel);
4966                 pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_RAW];
4967                 if (pPicChannel == NULL) {
4968                     LOGE("RAW Channel is NULL in Manual capture mode");
4969                     stopRAWChannel();
4970                     return UNKNOWN_ERROR;
4971                 }
4972             }
4973 
4974             rc = configureOnlineRotation(*pPicChannel);
4975             if (rc != NO_ERROR) {
4976                 LOGE("online rotation failed");
4977                 return rc;
4978             }
4979 
4980             // start postprocessor
4981             DeferWorkArgs args;
4982             memset(&args, 0, sizeof(DeferWorkArgs));
4983 
4984             args.pprocArgs = pPicChannel;
4985 
4986             // No need to wait for mInitPProcJob here, because it was
4987             // queued in startPreview, and will definitely be processed before
4988             // mReprocJob can begin.
4989             mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START,
4990                     args);
4991             if (mReprocJob == 0) {
4992                 LOGE("Failure: Unable to start pproc");
4993                 return -ENOMEM;
4994             }
4995 
4996             // Check if all preview buffers are mapped before creating
4997             // a jpeg session as preview stream buffers are queried during the same
4998             uint8_t numStreams = pChannel->getNumOfStreams();
4999             QCameraStream *pStream = NULL;
5000             QCameraStream *pPreviewStream = NULL;
5001             for (uint8_t i = 0 ; i < numStreams ; i++ ) {
5002                 pStream = pChannel->getStreamByIndex(i);
5003                 if (!pStream)
5004                     continue;
5005                 if (CAM_STREAM_TYPE_PREVIEW == pStream->getMyType()) {
5006                     pPreviewStream = pStream;
5007                     break;
5008                 }
5009             }
5010             if (pPreviewStream != NULL) {
5011                 Mutex::Autolock l(mMapLock);
5012                 QCameraMemory *pMemory = pStream->getStreamBufs();
5013                 if (!pMemory) {
5014                     LOGE("Error!! pMemory is NULL");
5015                     return -ENOMEM;
5016                 }
5017 
5018                 uint8_t waitCnt = 2;
5019                 while (!pMemory->checkIfAllBuffersMapped() && (waitCnt > 0)) {
5020                     LOGL(" Waiting for preview buffers to be mapped");
5021                     mMapCond.waitRelative(
5022                             mMapLock, CAMERA_DEFERRED_MAP_BUF_TIMEOUT);
5023                     LOGL("Wait completed!!");
5024                     waitCnt--;
5025                 }
5026                 // If all buffers are not mapped after retries, assert
5027                 assert(pMemory->checkIfAllBuffersMapped());
5028             } else {
5029                 assert(pPreviewStream);
5030             }
5031 
5032             // Create JPEG session
5033             mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION,
5034                     args);
5035             if (mJpegJob == 0) {
5036                 LOGE("Failed to queue CREATE_JPEG_SESSION");
5037                 if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5038                         LOGE("Reprocess Deferred work was failed");
5039                 }
5040                 m_postprocessor.stop();
5041                 return -ENOMEM;
5042             }
5043 
5044             if (mAdvancedCaptureConfigured) {
5045                 rc = startAdvancedCapture(pPicChannel);
5046                 if (rc != NO_ERROR) {
5047                     LOGE("cannot start zsl advanced capture");
5048                     return rc;
5049                 }
5050             }
5051             if (mLongshotEnabled && mPrepSnapRun) {
5052                 mCameraHandle->ops->start_zsl_snapshot(
5053                         mCameraHandle->camera_handle,
5054                         pPicChannel->getMyHandle());
5055             }
5056             // If frame sync is ON and it is a SECONDARY camera,
5057             // we do not need to send the take picture command to interface
5058             // It will be handled along with PRIMARY camera takePicture request
5059             mm_camera_req_buf_t buf;
5060             memset(&buf, 0x0, sizeof(buf));
5061             if ((!mParameters.isAdvCamFeaturesEnabled() &&
5062                     !mFlashNeeded &&
5063                     !isLongshotEnabled() &&
5064                     isFrameSyncEnabled()) &&
5065                     (getRelatedCamSyncInfo()->sync_control ==
5066                     CAM_SYNC_RELATED_SENSORS_ON)) {
5067                 if (getRelatedCamSyncInfo()->mode == CAM_MODE_PRIMARY) {
5068                     buf.type = MM_CAMERA_REQ_FRAME_SYNC_BUF;
5069                     buf.num_buf_requested = numSnapshots;
5070                     rc = pPicChannel->takePicture(&buf);
5071                     if (rc != NO_ERROR) {
5072                         LOGE("FS_DBG cannot take ZSL picture, stop pproc");
5073                         if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5074                             LOGE("Reprocess Deferred work failed");
5075                             return UNKNOWN_ERROR;
5076                         }
5077                         if (NO_ERROR != waitDeferredWork(mJpegJob)) {
5078                             LOGE("Jpeg Deferred work failed");
5079                             return UNKNOWN_ERROR;
5080                         }
5081                         m_postprocessor.stop();
5082                         return rc;
5083                     }
5084                     LOGI("PRIMARY camera: send frame sync takePicture!!");
5085                 }
5086             } else {
5087                 buf.type = MM_CAMERA_REQ_SUPER_BUF;
5088                 buf.num_buf_requested = numSnapshots;
5089                 buf.num_retro_buf_requested = numRetroSnapshots;
5090                 rc = pPicChannel->takePicture(&buf);
5091                 if (rc != NO_ERROR) {
5092                     LOGE("cannot take ZSL picture, stop pproc");
5093                         if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5094                             LOGE("Reprocess Deferred work failed");
5095                             return UNKNOWN_ERROR;
5096                         }
5097                         if (NO_ERROR != waitDeferredWork(mJpegJob)) {
5098                             LOGE("Jpeg Deferred work failed");
5099                             return UNKNOWN_ERROR;
5100                         }
5101                     m_postprocessor.stop();
5102                     return rc;
5103                 }
5104             }
5105         } else {
5106             LOGE("ZSL channel is NULL");
5107             return UNKNOWN_ERROR;
5108         }
5109     } else {
5110 
5111         // start snapshot
5112         if (mParameters.isJpegPictureFormat() ||
5113                 mParameters.isNV16PictureFormat() ||
5114                 mParameters.isNV21PictureFormat()) {
5115 
5116             //STOP Preview for Non ZSL use case
5117             stopPreview();
5118 
5119             //Config CAPTURE channels
5120             rc = declareSnapshotStreams();
5121             if (NO_ERROR != rc) {
5122                 return rc;
5123             }
5124 
5125             rc = addCaptureChannel();
5126             if ((rc == NO_ERROR) &&
5127                     (NULL != m_channels[QCAMERA_CH_TYPE_CAPTURE])) {
5128 
5129                 if (!mParameters.getofflineRAW()) {
5130                     rc = configureOnlineRotation(
5131                         *m_channels[QCAMERA_CH_TYPE_CAPTURE]);
5132                     if (rc != NO_ERROR) {
5133                         LOGE("online rotation failed");
5134                         delChannel(QCAMERA_CH_TYPE_CAPTURE);
5135                         return rc;
5136                     }
5137                 }
5138 
5139                 DeferWorkArgs args;
5140                 memset(&args, 0, sizeof(DeferWorkArgs));
5141 
5142                 args.pprocArgs = m_channels[QCAMERA_CH_TYPE_CAPTURE];
5143 
5144                 // No need to wait for mInitPProcJob here, because it was
5145                 // queued in startPreview, and will definitely be processed before
5146                 // mReprocJob can begin.
5147                 mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START,
5148                         args);
5149                 if (mReprocJob == 0) {
5150                     LOGE("Failure: Unable to start pproc");
5151                     return -ENOMEM;
5152                 }
5153 
5154                 // Create JPEG session
5155                 mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION,
5156                         args);
5157                 if (mJpegJob == 0) {
5158                     LOGE("Failed to queue CREATE_JPEG_SESSION");
5159                     if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5160                         LOGE("Reprocess Deferred work was failed");
5161                     }
5162                     m_postprocessor.stop();
5163                     return -ENOMEM;
5164                 }
5165 
5166                 // start catpure channel
5167                 rc =  m_channels[QCAMERA_CH_TYPE_CAPTURE]->start();
5168                 if (rc != NO_ERROR) {
5169                     LOGE("cannot start capture channel");
5170                     if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5171                         LOGE("Reprocess Deferred work failed");
5172                         return UNKNOWN_ERROR;
5173                     }
5174                     if (NO_ERROR != waitDeferredWork(mJpegJob)) {
5175                         LOGE("Jpeg Deferred work failed");
5176                         return UNKNOWN_ERROR;
5177                     }
5178                     delChannel(QCAMERA_CH_TYPE_CAPTURE);
5179                     return rc;
5180                 }
5181 
5182                 QCameraPicChannel *pCapChannel =
5183                     (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_CAPTURE];
5184                 if (NULL != pCapChannel) {
5185                     if (mParameters.isUbiFocusEnabled() ||
5186                             mParameters.isUbiRefocus() ||
5187                             mParameters.isChromaFlashEnabled()) {
5188                         rc = startAdvancedCapture(pCapChannel);
5189                         if (rc != NO_ERROR) {
5190                             LOGE("cannot start advanced capture");
5191                             return rc;
5192                         }
5193                     }
5194                 }
5195                 if ( mLongshotEnabled ) {
5196                     rc = longShot();
5197                     if (NO_ERROR != rc) {
5198                         if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5199                             LOGE("Reprocess Deferred work failed");
5200                             return UNKNOWN_ERROR;
5201                         }
5202                         if (NO_ERROR != waitDeferredWork(mJpegJob)) {
5203                             LOGE("Jpeg Deferred work failed");
5204                             return UNKNOWN_ERROR;
5205                         }
5206                         delChannel(QCAMERA_CH_TYPE_CAPTURE);
5207                         return rc;
5208                     }
5209                 }
5210             } else {
5211                 LOGE("cannot add capture channel");
5212                 delChannel(QCAMERA_CH_TYPE_CAPTURE);
5213                 return rc;
5214             }
5215         } else {
5216             // Stop Preview before taking NZSL snapshot
5217             stopPreview();
5218 
5219             rc = mParameters.updateRAW(gCamCapability[mCameraId]->raw_dim[0]);
5220             if (NO_ERROR != rc) {
5221                 LOGE("Raw dimension update failed %d", rc);
5222                 return rc;
5223             }
5224 
5225             rc = declareSnapshotStreams();
5226             if (NO_ERROR != rc) {
5227                 LOGE("RAW stream info configuration failed %d", rc);
5228                 return rc;
5229             }
5230 
5231             rc = addChannel(QCAMERA_CH_TYPE_RAW);
5232             if (rc == NO_ERROR) {
5233                 // start postprocessor
5234                 if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
5235                     LOGE("Reprocess Deferred work failed");
5236                     return UNKNOWN_ERROR;
5237                 }
5238 
5239                 rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]);
5240                 if (rc != NO_ERROR) {
5241                     LOGE("cannot start postprocessor");
5242                     delChannel(QCAMERA_CH_TYPE_RAW);
5243                     return rc;
5244                 }
5245 
5246                 rc = startChannel(QCAMERA_CH_TYPE_RAW);
5247                 if (rc != NO_ERROR) {
5248                     LOGE("cannot start raw channel");
5249                     m_postprocessor.stop();
5250                     delChannel(QCAMERA_CH_TYPE_RAW);
5251                     return rc;
5252                 }
5253             } else {
5254                 LOGE("cannot add raw channel");
5255                 return rc;
5256             }
5257         }
5258     }
5259 
5260     //When take picture, stop sending preview callbacks to APP
5261     m_stateMachine.setPreviewCallbackNeeded(false);
5262     LOGI("X rc = %d", rc);
5263     return rc;
5264 }
5265 
5266 /*===========================================================================
5267  * FUNCTION   : configureOnlineRotation
5268  *
5269  * DESCRIPTION: Configure backend with expected rotation for snapshot stream
5270  *
5271  * PARAMETERS :
5272  *    @ch     : Channel containing a snapshot stream
5273  *
5274  * RETURN     : int32_t type of status
5275  *              NO_ERROR  -- success
5276  *              none-zero failure code
5277  *==========================================================================*/
configureOnlineRotation(QCameraChannel & ch)5278 int32_t QCamera2HardwareInterface::configureOnlineRotation(QCameraChannel &ch)
5279 {
5280     int rc = NO_ERROR;
5281     uint32_t streamId = 0;
5282     QCameraStream *pStream = NULL;
5283 
5284     for (uint8_t i = 0; i < ch.getNumOfStreams(); i++) {
5285         QCameraStream *stream = ch.getStreamByIndex(i);
5286         if ((NULL != stream) &&
5287                 ((CAM_STREAM_TYPE_SNAPSHOT == stream->getMyType())
5288                 || (CAM_STREAM_TYPE_RAW == stream->getMyType()))) {
5289             pStream = stream;
5290             break;
5291         }
5292     }
5293 
5294     if (NULL == pStream) {
5295         LOGE("No snapshot stream found!");
5296         return BAD_VALUE;
5297     }
5298 
5299     streamId = pStream->getMyServerID();
5300     // Update online rotation configuration
5301     rc = mParameters.addOnlineRotation(mParameters.getJpegRotation(), streamId,
5302             mParameters.getDeviceRotation());
5303     if (rc != NO_ERROR) {
5304         LOGE("addOnlineRotation failed %d", rc);
5305         return rc;
5306     }
5307 
5308     return rc;
5309 }
5310 
5311 /*===========================================================================
5312  * FUNCTION   : declareSnapshotStreams
5313  *
5314  * DESCRIPTION: Configure backend with expected snapshot streams
5315  *
5316  * PARAMETERS : none
5317  *
5318  * RETURN     : int32_t type of status
5319  *              NO_ERROR  -- success
5320  *              none-zero failure code
5321  *==========================================================================*/
declareSnapshotStreams()5322 int32_t QCamera2HardwareInterface::declareSnapshotStreams()
5323 {
5324     int rc = NO_ERROR;
5325 
5326     // Update stream info configuration
5327     rc = mParameters.setStreamConfigure(true, mLongshotEnabled, false);
5328     if (rc != NO_ERROR) {
5329         LOGE("setStreamConfigure failed %d", rc);
5330         return rc;
5331     }
5332 
5333     return rc;
5334 }
5335 
5336 /*===========================================================================
5337  * FUNCTION   : longShot
5338  *
5339  * DESCRIPTION: Queue one more ZSL frame
5340  *              in the longshot pipe.
5341  *
5342  * PARAMETERS : none
5343  *
5344  * RETURN     : int32_t type of status
5345  *              NO_ERROR  -- success
5346  *              none-zero failure code
5347  *==========================================================================*/
longShot()5348 int32_t QCamera2HardwareInterface::longShot()
5349 {
5350     int32_t rc = NO_ERROR;
5351     uint8_t numSnapshots = mParameters.getNumOfSnapshots();
5352     QCameraPicChannel *pChannel = NULL;
5353 
5354     if (mParameters.isZSLMode()) {
5355         pChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
5356     } else {
5357         pChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_CAPTURE];
5358     }
5359 
5360     if (NULL != pChannel) {
5361         mm_camera_req_buf_t buf;
5362         memset(&buf, 0x0, sizeof(buf));
5363         buf.type = MM_CAMERA_REQ_SUPER_BUF;
5364         buf.num_buf_requested = numSnapshots;
5365         rc = pChannel->takePicture(&buf);
5366     } else {
5367         LOGE("Capture channel not initialized!");
5368         rc = NO_INIT;
5369         goto end;
5370     }
5371 
5372 end:
5373     return rc;
5374 }
5375 
5376 /*===========================================================================
5377  * FUNCTION   : stopCaptureChannel
5378  *
5379  * DESCRIPTION: Stops capture channel
5380  *
5381  * PARAMETERS :
5382  *   @destroy : Set to true to stop and delete camera channel.
5383  *              Set to false to only stop capture channel.
5384  *
5385  * RETURN     : int32_t type of status
5386  *              NO_ERROR  -- success
5387  *              none-zero failure code
5388  *==========================================================================*/
stopCaptureChannel(bool destroy)5389 int QCamera2HardwareInterface::stopCaptureChannel(bool destroy)
5390 {
5391     int rc = NO_ERROR;
5392     if (mParameters.isJpegPictureFormat() ||
5393         mParameters.isNV16PictureFormat() ||
5394         mParameters.isNV21PictureFormat()) {
5395         mParameters.setQuadraCfaMode(false, true);
5396         rc = stopChannel(QCAMERA_CH_TYPE_CAPTURE);
5397         if (destroy && (NO_ERROR == rc)) {
5398             // Destroy camera channel but dont release context
5399             waitDeferredWork(mJpegJob);
5400             rc = delChannel(QCAMERA_CH_TYPE_CAPTURE, false);
5401         }
5402     }
5403 
5404     return rc;
5405 }
5406 
5407 /*===========================================================================
5408  * FUNCTION   : cancelPicture
5409  *
5410  * DESCRIPTION: cancel picture impl
5411  *
5412  * PARAMETERS : none
5413  *
5414  * RETURN     : int32_t type of status
5415  *              NO_ERROR  -- success
5416  *              none-zero failure code
5417  *==========================================================================*/
cancelPicture()5418 int QCamera2HardwareInterface::cancelPicture()
5419 {
5420     waitDeferredWork(mReprocJob);
5421     waitDeferredWork(mJpegJob);
5422 
5423     //stop post processor
5424     m_postprocessor.stop();
5425 
5426     unconfigureAdvancedCapture();
5427     LOGH("Enable display frames again");
5428     setDisplaySkip(FALSE);
5429 
5430     if (mParameters.isZSLMode()) {
5431         QCameraPicChannel *pPicChannel = NULL;
5432         if (mParameters.getofflineRAW()) {
5433             pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_RAW];
5434         } else {
5435             pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
5436         }
5437         if (NULL != pPicChannel) {
5438             pPicChannel->cancelPicture();
5439             stopRAWChannel();
5440             stopAdvancedCapture(pPicChannel);
5441         }
5442     } else {
5443 
5444         // normal capture case
5445         if (mParameters.isJpegPictureFormat() ||
5446             mParameters.isNV16PictureFormat() ||
5447             mParameters.isNV21PictureFormat()) {
5448             stopChannel(QCAMERA_CH_TYPE_CAPTURE);
5449             delChannel(QCAMERA_CH_TYPE_CAPTURE);
5450         } else {
5451             stopChannel(QCAMERA_CH_TYPE_RAW);
5452             delChannel(QCAMERA_CH_TYPE_RAW);
5453         }
5454     }
5455 
5456     return NO_ERROR;
5457 }
5458 
5459 /*===========================================================================
5460  * FUNCTION   : captureDone
5461  *
5462  * DESCRIPTION: Function called when the capture is completed before encoding
5463  *
5464  * PARAMETERS : none
5465  *
5466  * RETURN     : none
5467  *==========================================================================*/
captureDone()5468 void QCamera2HardwareInterface::captureDone()
5469 {
5470     qcamera_sm_internal_evt_payload_t *payload =
5471        (qcamera_sm_internal_evt_payload_t *)
5472        malloc(sizeof(qcamera_sm_internal_evt_payload_t));
5473     if (NULL != payload) {
5474         memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
5475         payload->evt_type = QCAMERA_INTERNAL_EVT_ZSL_CAPTURE_DONE;
5476         int32_t rc = processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
5477         if (rc != NO_ERROR) {
5478             LOGE("processEvt ZSL capture done failed");
5479             free(payload);
5480             payload = NULL;
5481         }
5482     } else {
5483         LOGE("No memory for ZSL capture done event");
5484     }
5485 }
5486 
5487 /*===========================================================================
5488  * FUNCTION   : Live_Snapshot_thread
5489  *
5490  * DESCRIPTION: Seperate thread for taking live snapshot during recording
5491  *
5492  * PARAMETERS : @data - pointer to QCamera2HardwareInterface class object
5493  *
5494  * RETURN     : none
5495  *==========================================================================*/
Live_Snapshot_thread(void * data)5496 void* Live_Snapshot_thread (void* data)
5497 {
5498 
5499     QCamera2HardwareInterface *hw = reinterpret_cast<QCamera2HardwareInterface *>(data);
5500     if (!hw) {
5501         LOGE("take_picture_thread: NULL camera device");
5502         return (void *)BAD_VALUE;
5503     }
5504     if (hw->bLiveSnapshot) {
5505         hw->takeLiveSnapshot_internal();
5506     } else {
5507         hw->cancelLiveSnapshot_internal();
5508     }
5509     return (void* )NULL;
5510 }
5511 
5512 /*===========================================================================
5513  * FUNCTION   : Int_Pic_thread
5514  *
5515  * DESCRIPTION: Seperate thread for taking snapshot triggered by camera backend
5516  *
5517  * PARAMETERS : @data - pointer to QCamera2HardwareInterface class object
5518  *
5519  * RETURN     : none
5520  *==========================================================================*/
Int_Pic_thread(void * data)5521 void* Int_Pic_thread (void* data)
5522 {
5523     int rc = NO_ERROR;
5524 
5525     QCamera2HardwareInterface *hw = reinterpret_cast<QCamera2HardwareInterface *>(data);
5526 
5527     if (!hw) {
5528         LOGE("take_picture_thread: NULL camera device");
5529         return (void *)BAD_VALUE;
5530     }
5531 
5532     bool JpegMemOpt = false;
5533     char raw_format[PROPERTY_VALUE_MAX];
5534 
5535     memset(raw_format, 0, sizeof(raw_format));
5536 
5537     rc = hw->takeBackendPic_internal(&JpegMemOpt, &raw_format[0]);
5538     if (rc == NO_ERROR) {
5539         hw->checkIntPicPending(JpegMemOpt, &raw_format[0]);
5540     } else {
5541         //Snapshot attempt not successful, we need to do cleanup here
5542         hw->clearIntPendingEvents();
5543     }
5544 
5545     return (void* )NULL;
5546 }
5547 
5548 /*===========================================================================
5549  * FUNCTION   : takeLiveSnapshot
5550  *
5551  * DESCRIPTION: take live snapshot during recording
5552  *
5553  * PARAMETERS : none
5554  *
5555  * RETURN     : int32_t type of status
5556  *              NO_ERROR  -- success
5557  *              none-zero failure code
5558  *==========================================================================*/
takeLiveSnapshot()5559 int QCamera2HardwareInterface::takeLiveSnapshot()
5560 {
5561     int rc = NO_ERROR;
5562     if (mLiveSnapshotThread != 0) {
5563         pthread_join(mLiveSnapshotThread,NULL);
5564         mLiveSnapshotThread = 0;
5565     }
5566     bLiveSnapshot = true;
5567     rc= pthread_create(&mLiveSnapshotThread, NULL, Live_Snapshot_thread, (void *) this);
5568     if (!rc) {
5569         pthread_setname_np(mLiveSnapshotThread, "CAM_liveSnap");
5570     }
5571     return rc;
5572 }
5573 
5574 /*===========================================================================
5575  * FUNCTION   : takePictureInternal
5576  *
5577  * DESCRIPTION: take snapshot triggered by backend
5578  *
5579  * PARAMETERS : none
5580  *
5581  * RETURN     : int32_t type of status
5582  *              NO_ERROR  -- success
5583  *              none-zero failure code
5584  *==========================================================================*/
takePictureInternal()5585 int QCamera2HardwareInterface::takePictureInternal()
5586 {
5587     int rc = NO_ERROR;
5588     rc= pthread_create(&mIntPicThread, NULL, Int_Pic_thread, (void *) this);
5589     if (!rc) {
5590         pthread_setname_np(mIntPicThread, "CAM_IntPic");
5591     }
5592     return rc;
5593 }
5594 
5595 /*===========================================================================
5596  * FUNCTION   : checkIntPicPending
5597  *
5598  * DESCRIPTION: timed wait for jpeg completion event, and send
5599  *                        back completion event to backend
5600  *
5601  * PARAMETERS : none
5602  *
5603  * RETURN     : none
5604  *==========================================================================*/
checkIntPicPending(bool JpegMemOpt,char * raw_format)5605 void QCamera2HardwareInterface::checkIntPicPending(bool JpegMemOpt, char *raw_format)
5606 {
5607     bool bSendToBackend = true;
5608     cam_int_evt_params_t params;
5609     int rc = NO_ERROR;
5610 
5611     struct timespec   ts;
5612     struct timeval    tp;
5613     gettimeofday(&tp, NULL);
5614     ts.tv_sec  = tp.tv_sec + 5;
5615     ts.tv_nsec = tp.tv_usec * 1000;
5616 
5617     if (true == m_bIntJpegEvtPending ||
5618         (true == m_bIntRawEvtPending)) {
5619         //Waiting in HAL for snapshot taken notification
5620         pthread_mutex_lock(&m_int_lock);
5621         rc = pthread_cond_timedwait(&m_int_cond, &m_int_lock, &ts);
5622         if (ETIMEDOUT == rc || 0x0 == m_BackendFileName[0]) {
5623             //Hit a timeout, or some spurious activity
5624             bSendToBackend = false;
5625         }
5626 
5627         if (true == m_bIntJpegEvtPending) {
5628             params.event_type = 0;
5629             mParameters.getStreamFormat(CAM_STREAM_TYPE_SNAPSHOT, params.picture_format);
5630         } else if (true == m_bIntRawEvtPending) {
5631             params.event_type = 1;
5632             mParameters.getStreamFormat(CAM_STREAM_TYPE_RAW, params.picture_format);
5633         }
5634         pthread_mutex_unlock(&m_int_lock);
5635 
5636         if (true == m_bIntJpegEvtPending) {
5637             //Attempting to restart preview after taking JPEG snapshot
5638             lockAPI();
5639             rc = processAPI(QCAMERA_SM_EVT_SNAPSHOT_DONE, NULL);
5640             unlockAPI();
5641             m_postprocessor.setJpegMemOpt(JpegMemOpt);
5642         } else if (true == m_bIntRawEvtPending) {
5643             //Attempting to restart preview after taking RAW snapshot
5644             stopChannel(QCAMERA_CH_TYPE_RAW);
5645             delChannel(QCAMERA_CH_TYPE_RAW);
5646             //restoring the old raw format
5647             property_set("persist.camera.raw.format", raw_format);
5648         }
5649 
5650         if (true == bSendToBackend) {
5651             //send event back to server with the file path
5652             params.dim = m_postprocessor.m_dst_dim;
5653             memcpy(&params.path[0], &m_BackendFileName[0], QCAMERA_MAX_FILEPATH_LENGTH);
5654             memset(&m_BackendFileName[0], 0x0, QCAMERA_MAX_FILEPATH_LENGTH);
5655             params.size = mBackendFileSize;
5656             rc = mParameters.setIntEvent(params);
5657         }
5658 
5659         clearIntPendingEvents();
5660     }
5661 
5662     return;
5663 }
5664 
5665 /*===========================================================================
5666  * FUNCTION   : takeBackendPic_internal
5667  *
5668  * DESCRIPTION: take snapshot triggered by backend
5669  *
5670  * PARAMETERS : none
5671  *
5672  * RETURN     : int32_t type of status
5673  *              NO_ERROR  -- success
5674  *              none-zero failure code
5675  *==========================================================================*/
takeBackendPic_internal(bool * JpegMemOpt,char * raw_format)5676 int QCamera2HardwareInterface::takeBackendPic_internal(bool *JpegMemOpt, char *raw_format)
5677 {
5678     int rc = NO_ERROR;
5679     qcamera_api_result_t apiResult;
5680 
5681     lockAPI();
5682     //Set rotation value from user settings as Jpeg rotation
5683     //to configure back-end modules.
5684     mParameters.setJpegRotation(mParameters.getRotation());
5685 
5686     setRetroPicture(0);
5687     /* Prepare snapshot in case LED needs to be flashed */
5688     if (mFlashNeeded == 1 || mParameters.isChromaFlashEnabled()) {
5689         // Start Preparing for normal Frames
5690         LOGH("Start Prepare Snapshot");
5691         /* Prepare snapshot in case LED needs to be flashed */
5692         rc = processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL);
5693         if (rc == NO_ERROR) {
5694             waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, &apiResult);
5695             rc = apiResult.status;
5696         }
5697         LOGH("Prep Snapshot done rc = %d", rc);
5698         mPrepSnapRun = true;
5699     }
5700     unlockAPI();
5701 
5702     if (true == m_bIntJpegEvtPending) {
5703         //Attempting to take JPEG snapshot
5704         if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
5705             LOGE("Init PProc Deferred work failed");
5706             return UNKNOWN_ERROR;
5707         }
5708         *JpegMemOpt = m_postprocessor.getJpegMemOpt();
5709         m_postprocessor.setJpegMemOpt(false);
5710 
5711         /* capture */
5712         lockAPI();
5713         LOGH("Capturing internal snapshot");
5714         rc = processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL);
5715         if (rc == NO_ERROR) {
5716             waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult);
5717             rc = apiResult.status;
5718         }
5719         unlockAPI();
5720     } else if (true == m_bIntRawEvtPending) {
5721         //Attempting to take RAW snapshot
5722         (void)JpegMemOpt;
5723         stopPreview();
5724 
5725         //getting the existing raw format type
5726         property_get("persist.camera.raw.format", raw_format, "17");
5727         //setting it to a default know value for this task
5728         property_set("persist.camera.raw.format", "18");
5729 
5730         rc = addChannel(QCAMERA_CH_TYPE_RAW);
5731         if (rc == NO_ERROR) {
5732             // start postprocessor
5733             if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
5734                 LOGE("Init PProc Deferred work failed");
5735                 return UNKNOWN_ERROR;
5736             }
5737             rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]);
5738             if (rc != NO_ERROR) {
5739                 LOGE("cannot start postprocessor");
5740                 delChannel(QCAMERA_CH_TYPE_RAW);
5741                 return rc;
5742             }
5743 
5744             rc = startChannel(QCAMERA_CH_TYPE_RAW);
5745             if (rc != NO_ERROR) {
5746                 LOGE("cannot start raw channel");
5747                 m_postprocessor.stop();
5748                 delChannel(QCAMERA_CH_TYPE_RAW);
5749                 return rc;
5750             }
5751         } else {
5752             LOGE("cannot add raw channel");
5753             return rc;
5754         }
5755     }
5756 
5757     return rc;
5758 }
5759 
5760 /*===========================================================================
5761  * FUNCTION   : clearIntPendingEvents
5762  *
5763  * DESCRIPTION: clear internal pending events pertaining to backend
5764  *                        snapshot requests
5765  *
5766  * PARAMETERS : none
5767  *
5768  * RETURN     : int32_t type of status
5769  *              NO_ERROR  -- success
5770  *              none-zero failure code
5771  *==========================================================================*/
clearIntPendingEvents()5772 void QCamera2HardwareInterface::clearIntPendingEvents()
5773 {
5774     int rc = NO_ERROR;
5775 
5776     if (true == m_bIntRawEvtPending) {
5777         preparePreview();
5778         startPreview();
5779     }
5780     if (true == m_bIntJpegEvtPending) {
5781         if (false == mParameters.isZSLMode()) {
5782             lockAPI();
5783             rc = processAPI(QCAMERA_SM_EVT_START_PREVIEW, NULL);
5784             unlockAPI();
5785         }
5786     }
5787 
5788     pthread_mutex_lock(&m_int_lock);
5789     if (true == m_bIntJpegEvtPending) {
5790         m_bIntJpegEvtPending = false;
5791     } else if (true == m_bIntRawEvtPending) {
5792         m_bIntRawEvtPending = false;
5793     }
5794     pthread_mutex_unlock(&m_int_lock);
5795     return;
5796 }
5797 
5798 /*===========================================================================
5799  * FUNCTION   : takeLiveSnapshot_internal
5800  *
5801  * DESCRIPTION: take live snapshot during recording
5802  *
5803  * PARAMETERS : none
5804  *
5805  * RETURN     : int32_t type of status
5806  *              NO_ERROR  -- success
5807  *              none-zero failure code
5808  *==========================================================================*/
takeLiveSnapshot_internal()5809 int QCamera2HardwareInterface::takeLiveSnapshot_internal()
5810 {
5811     int rc = NO_ERROR;
5812 
5813     QCameraChannel *pChannel = NULL;
5814     QCameraChannel *pPreviewChannel = NULL;
5815     QCameraStream  *pPreviewStream = NULL;
5816     QCameraStream  *pStream = NULL;
5817 
5818     //Set rotation value from user settings as Jpeg rotation
5819     //to configure back-end modules.
5820     mParameters.setJpegRotation(mParameters.getRotation());
5821 
5822     // Configure advanced capture
5823     rc = configureAdvancedCapture();
5824     if (rc != NO_ERROR) {
5825         LOGE("Unsupported capture call");
5826         goto end;
5827     }
5828 
5829     if (isLowPowerMode()) {
5830         pChannel = m_channels[QCAMERA_CH_TYPE_VIDEO];
5831     } else {
5832         pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
5833     }
5834 
5835     if (NULL == pChannel) {
5836         LOGE("Snapshot/Video channel not initialized");
5837         rc = NO_INIT;
5838         goto end;
5839     }
5840 
5841     // Check if all preview buffers are mapped before creating
5842     // a jpeg session as preview stream buffers are queried during the same
5843     pPreviewChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
5844     if (pPreviewChannel != NULL) {
5845         uint32_t numStreams = pPreviewChannel->getNumOfStreams();
5846 
5847         for (uint8_t i = 0 ; i < numStreams ; i++ ) {
5848             pStream = pPreviewChannel->getStreamByIndex(i);
5849             if (!pStream)
5850                 continue;
5851             if (CAM_STREAM_TYPE_PREVIEW == pStream->getMyType()) {
5852                 pPreviewStream = pStream;
5853                 break;
5854             }
5855         }
5856 
5857         if (pPreviewStream != NULL) {
5858             Mutex::Autolock l(mMapLock);
5859             QCameraMemory *pMemory = pStream->getStreamBufs();
5860             if (!pMemory) {
5861                 LOGE("Error!! pMemory is NULL");
5862                 return -ENOMEM;
5863             }
5864 
5865             uint8_t waitCnt = 2;
5866             while (!pMemory->checkIfAllBuffersMapped() && (waitCnt > 0)) {
5867                 LOGL(" Waiting for preview buffers to be mapped");
5868                 mMapCond.waitRelative(
5869                         mMapLock, CAMERA_DEFERRED_MAP_BUF_TIMEOUT);
5870                 LOGL("Wait completed!!");
5871                 waitCnt--;
5872             }
5873             // If all buffers are not mapped after retries, assert
5874             assert(pMemory->checkIfAllBuffersMapped());
5875         } else {
5876             assert(pPreviewStream);
5877         }
5878     }
5879 
5880     DeferWorkArgs args;
5881     memset(&args, 0, sizeof(DeferWorkArgs));
5882 
5883     args.pprocArgs = pChannel;
5884 
5885     // No need to wait for mInitPProcJob here, because it was
5886     // queued in startPreview, and will definitely be processed before
5887     // mReprocJob can begin.
5888     mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START,
5889             args);
5890     if (mReprocJob == 0) {
5891         LOGE("Failed to queue CMD_DEF_PPROC_START");
5892         rc = -ENOMEM;
5893         goto end;
5894     }
5895 
5896     // Create JPEG session
5897     mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION,
5898             args);
5899     if (mJpegJob == 0) {
5900         LOGE("Failed to queue CREATE_JPEG_SESSION");
5901         if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5902             LOGE("Reprocess Deferred work was failed");
5903         }
5904         m_postprocessor.stop();
5905         rc = -ENOMEM;
5906         goto end;
5907     }
5908 
5909     if (isLowPowerMode()) {
5910         mm_camera_req_buf_t buf;
5911         memset(&buf, 0x0, sizeof(buf));
5912         buf.type = MM_CAMERA_REQ_SUPER_BUF;
5913         buf.num_buf_requested = 1;
5914         rc = ((QCameraVideoChannel*)pChannel)->takePicture(&buf);
5915         goto end;
5916     }
5917 
5918     //Disable reprocess for 4K liveshot case
5919     if (!mParameters.is4k2kVideoResolution()) {
5920         rc = configureOnlineRotation(*m_channels[QCAMERA_CH_TYPE_SNAPSHOT]);
5921         if (rc != NO_ERROR) {
5922             LOGE("online rotation failed");
5923             if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5924                 LOGE("Reprocess Deferred work was failed");
5925             }
5926             if (NO_ERROR != waitDeferredWork(mJpegJob)) {
5927                 LOGE("Jpeg Deferred work was failed");
5928             }
5929             m_postprocessor.stop();
5930             return rc;
5931         }
5932     }
5933 
5934     if ((NULL != pChannel) && (mParameters.isTNRSnapshotEnabled())) {
5935         QCameraStream *pStream = NULL;
5936         for (uint32_t i = 0 ; i < pChannel->getNumOfStreams(); i++ ) {
5937             pStream = pChannel->getStreamByIndex(i);
5938             if ((NULL != pStream) &&
5939                     (CAM_STREAM_TYPE_SNAPSHOT == pStream->getMyType())) {
5940                 break;
5941             }
5942         }
5943         if (pStream != NULL) {
5944             LOGD("REQUEST_FRAMES event for TNR snapshot");
5945             cam_stream_parm_buffer_t param;
5946             memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
5947             param.type = CAM_STREAM_PARAM_TYPE_REQUEST_FRAMES;
5948             param.frameRequest.enableStream = 1;
5949             rc = pStream->setParameter(param);
5950             if (rc != NO_ERROR) {
5951                 LOGE("Stream Event REQUEST_FRAMES failed");
5952             }
5953             goto end;
5954         }
5955     }
5956 
5957     // start snapshot channel
5958     if ((rc == NO_ERROR) && (NULL != pChannel)) {
5959         // Do not link metadata stream for 4K2k resolution
5960         // as CPP processing would be done on snapshot stream and not
5961         // reprocess stream
5962         if (!mParameters.is4k2kVideoResolution()) {
5963             // Find and try to link a metadata stream from preview channel
5964             QCameraChannel *pMetaChannel = NULL;
5965             QCameraStream *pMetaStream = NULL;
5966             QCameraStream *pPreviewStream = NULL;
5967 
5968             if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
5969                 pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
5970                 uint32_t streamNum = pMetaChannel->getNumOfStreams();
5971                 QCameraStream *pStream = NULL;
5972                 for (uint32_t i = 0 ; i < streamNum ; i++ ) {
5973                     pStream = pMetaChannel->getStreamByIndex(i);
5974                     if (NULL != pStream) {
5975                         if (CAM_STREAM_TYPE_METADATA == pStream->getMyType()) {
5976                             pMetaStream = pStream;
5977                         } else if ((CAM_STREAM_TYPE_PREVIEW == pStream->getMyType())
5978                                 && (!mParameters.isHfrMode())
5979                                 && (mParameters.isLinkPreviewForLiveShot())) {
5980                             // Do not link preview stream for
5981                             // 1)HFR live snapshot,Thumbnail will not be derived from
5982                             //   preview for HFR live snapshot.
5983                             // 2)persist.camera.linkpreview is 0
5984                             pPreviewStream = pStream;
5985                         }
5986                     }
5987                 }
5988             }
5989 
5990             if ((NULL != pMetaChannel) && (NULL != pMetaStream)) {
5991                 rc = pChannel->linkStream(pMetaChannel, pMetaStream);
5992                 if (NO_ERROR != rc) {
5993                     LOGE("Metadata stream link failed %d", rc);
5994                 }
5995             }
5996             if ((NULL != pMetaChannel) && (NULL != pPreviewStream)) {
5997                 rc = pChannel->linkStream(pMetaChannel, pPreviewStream);
5998                 if (NO_ERROR != rc) {
5999                     LOGE("Preview stream link failed %d", rc);
6000                 }
6001             }
6002         }
6003         rc = pChannel->start();
6004     }
6005 
6006 end:
6007     if (rc != NO_ERROR) {
6008         rc = processAPI(QCAMERA_SM_EVT_CANCEL_PICTURE, NULL);
6009         rc = sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
6010     }
6011     return rc;
6012 }
6013 
6014 /*===========================================================================
6015  * FUNCTION   : cancelLiveSnapshot
6016  *
6017  * DESCRIPTION: cancel current live snapshot request
6018  *
6019  * PARAMETERS : none
6020  *
6021  * RETURN     : int32_t type of status
6022  *              NO_ERROR  -- success
6023  *              none-zero failure code
6024  *==========================================================================*/
cancelLiveSnapshot()6025 int QCamera2HardwareInterface::cancelLiveSnapshot()
6026 {
6027     int rc = NO_ERROR;
6028     if (mLiveSnapshotThread != 0) {
6029         pthread_join(mLiveSnapshotThread,NULL);
6030         mLiveSnapshotThread = 0;
6031     }
6032     bLiveSnapshot = false;
6033     rc= pthread_create(&mLiveSnapshotThread, NULL, Live_Snapshot_thread, (void *) this);
6034     if (!rc) {
6035         pthread_setname_np(mLiveSnapshotThread, "CAM_cancel_liveSnap");
6036     }
6037     return rc;
6038 }
6039 
6040 /*===========================================================================
6041  * FUNCTION   : cancelLiveSnapshot_internal
6042  *
6043  * DESCRIPTION: cancel live snapshot during recording
6044  *
6045  * PARAMETERS : none
6046  *
6047  * RETURN     : int32_t type of status
6048  *              NO_ERROR  -- success
6049  *              none-zero failure code
6050  *==========================================================================*/
cancelLiveSnapshot_internal()6051 int QCamera2HardwareInterface::cancelLiveSnapshot_internal() {
6052     int rc = NO_ERROR;
6053 
6054     unconfigureAdvancedCapture();
6055     LOGH("Enable display frames again");
6056     setDisplaySkip(FALSE);
6057 
6058     //wait for deferred (reprocess and jpeg) threads to finish
6059     waitDeferredWork(mReprocJob);
6060     waitDeferredWork(mJpegJob);
6061     //stop post processor
6062     m_postprocessor.stop();
6063 
6064     // stop snapshot channel
6065     if (!mParameters.isTNRSnapshotEnabled()) {
6066         rc = stopChannel(QCAMERA_CH_TYPE_SNAPSHOT);
6067     } else {
6068         QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
6069         if (NULL != pChannel) {
6070             QCameraStream *pStream = NULL;
6071             for (uint32_t i = 0 ; i < pChannel->getNumOfStreams(); i++ ) {
6072                 pStream = pChannel->getStreamByIndex(i);
6073                 if ((NULL != pStream) &&
6074                         (CAM_STREAM_TYPE_SNAPSHOT ==
6075                         pStream->getMyType())) {
6076                     break;
6077                 }
6078             }
6079             if (pStream != NULL) {
6080                 LOGD("REQUEST_FRAMES event for TNR snapshot");
6081                 cam_stream_parm_buffer_t param;
6082                 memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
6083                 param.type = CAM_STREAM_PARAM_TYPE_REQUEST_FRAMES;
6084                 param.frameRequest.enableStream = 0;
6085                 rc = pStream->setParameter(param);
6086                 if (rc != NO_ERROR) {
6087                     LOGE("Stream Event REQUEST_FRAMES failed");
6088                 }
6089             }
6090         }
6091     }
6092 
6093     return rc;
6094 }
6095 
6096 /*===========================================================================
6097  * FUNCTION   : putParameters
6098  *
6099  * DESCRIPTION: put parameters string impl
6100  *
6101  * PARAMETERS :
6102  *   @parms   : parameters string to be released
6103  *
6104  * RETURN     : int32_t type of status
6105  *              NO_ERROR  -- success
6106  *              none-zero failure code
6107  *==========================================================================*/
putParameters(char * parms)6108 int QCamera2HardwareInterface::putParameters(char *parms)
6109 {
6110     free(parms);
6111     return NO_ERROR;
6112 }
6113 
6114 /*===========================================================================
6115  * FUNCTION   : sendCommand
6116  *
6117  * DESCRIPTION: send command impl
6118  *
6119  * PARAMETERS :
6120  *   @command : command to be executed
6121  *   @arg1    : optional argument 1
6122  *   @arg2    : optional argument 2
6123  *
6124  * RETURN     : int32_t type of status
6125  *              NO_ERROR  -- success
6126  *              none-zero failure code
6127  *==========================================================================*/
sendCommand(int32_t command,__unused int32_t & arg1,__unused int32_t & arg2)6128 int QCamera2HardwareInterface::sendCommand(int32_t command,
6129         __unused int32_t &arg1, __unused int32_t &arg2)
6130 {
6131     int rc = NO_ERROR;
6132 
6133     switch (command) {
6134 #ifndef VANILLA_HAL
6135     case CAMERA_CMD_LONGSHOT_ON:
6136         arg1 = arg2 = 0;
6137         // Longshot can only be enabled when image capture
6138         // is not active.
6139         if ( !m_stateMachine.isCaptureRunning() ) {
6140             LOGI("Longshot Enabled");
6141             mLongshotEnabled = true;
6142             rc = mParameters.setLongshotEnable(mLongshotEnabled);
6143 
6144             // Due to recent buffer count optimizations
6145             // ZSL might run with considerably less buffers
6146             // when not in longshot mode. Preview needs to
6147             // restart in this case.
6148             if (isZSLMode() && m_stateMachine.isPreviewRunning()) {
6149                 QCameraChannel *pChannel = NULL;
6150                 QCameraStream *pSnapStream = NULL;
6151                 pChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
6152                 if (NULL != pChannel) {
6153                     QCameraStream *pStream = NULL;
6154                     for (uint32_t i = 0; i < pChannel->getNumOfStreams(); i++) {
6155                         pStream = pChannel->getStreamByIndex(i);
6156                         if (pStream != NULL) {
6157                             if (pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT)) {
6158                                 pSnapStream = pStream;
6159                                 break;
6160                             }
6161                         }
6162                     }
6163                     if (NULL != pSnapStream) {
6164                         uint8_t required = 0;
6165                         required = getBufNumRequired(CAM_STREAM_TYPE_SNAPSHOT);
6166                         if (pSnapStream->getBufferCount() < required) {
6167                             // We restart here, to reset the FPS and no
6168                             // of buffers as per the requirement of longshot usecase.
6169                             arg1 = QCAMERA_SM_EVT_RESTART_PERVIEW;
6170                             if (getRelatedCamSyncInfo()->sync_control ==
6171                                     CAM_SYNC_RELATED_SENSORS_ON) {
6172                                 arg2 = QCAMERA_SM_EVT_DELAYED_RESTART;
6173                             }
6174                         }
6175                     }
6176                 }
6177             }
6178             //
6179             mPrepSnapRun = false;
6180             mCACDoneReceived = FALSE;
6181         } else {
6182             rc = NO_INIT;
6183         }
6184         break;
6185     case CAMERA_CMD_LONGSHOT_OFF:
6186         if ( mLongshotEnabled && m_stateMachine.isCaptureRunning() ) {
6187             cancelPicture();
6188             processEvt(QCAMERA_SM_EVT_SNAPSHOT_DONE, NULL);
6189             QCameraChannel *pZSLChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
6190             if (isZSLMode() && (NULL != pZSLChannel) && mPrepSnapRun) {
6191                 mCameraHandle->ops->stop_zsl_snapshot(
6192                         mCameraHandle->camera_handle,
6193                         pZSLChannel->getMyHandle());
6194             }
6195         }
6196         mPrepSnapRun = false;
6197         LOGI("Longshot Disabled");
6198         mLongshotEnabled = false;
6199         rc = mParameters.setLongshotEnable(mLongshotEnabled);
6200         mCACDoneReceived = FALSE;
6201         break;
6202     case CAMERA_CMD_HISTOGRAM_ON:
6203     case CAMERA_CMD_HISTOGRAM_OFF:
6204         rc = setHistogram(command == CAMERA_CMD_HISTOGRAM_ON? true : false);
6205         LOGH("Histogram -> %s",
6206               mParameters.isHistogramEnabled() ? "Enabled" : "Disabled");
6207         break;
6208 #endif
6209     case CAMERA_CMD_START_FACE_DETECTION:
6210     case CAMERA_CMD_STOP_FACE_DETECTION:
6211         mParameters.setFaceDetectionOption(command == CAMERA_CMD_START_FACE_DETECTION? true : false);
6212         rc = setFaceDetection(command == CAMERA_CMD_START_FACE_DETECTION? true : false);
6213         LOGH("FaceDetection -> %s",
6214               mParameters.isFaceDetectionEnabled() ? "Enabled" : "Disabled");
6215         break;
6216 #ifndef VANILLA_HAL
6217     case CAMERA_CMD_HISTOGRAM_SEND_DATA:
6218 #endif
6219     default:
6220         rc = NO_ERROR;
6221         break;
6222     }
6223     return rc;
6224 }
6225 
6226 /*===========================================================================
6227  * FUNCTION   : registerFaceImage
6228  *
6229  * DESCRIPTION: register face image impl
6230  *
6231  * PARAMETERS :
6232  *   @img_ptr : ptr to image buffer
6233  *   @config  : ptr to config struct about input image info
6234  *   @faceID  : [OUT] face ID to uniquely identifiy the registered face image
6235  *
6236  * RETURN     : int32_t type of status
6237  *              NO_ERROR  -- success
6238  *              none-zero failure code
6239  *==========================================================================*/
registerFaceImage(void * img_ptr,cam_pp_offline_src_config_t * config,int32_t & faceID)6240 int QCamera2HardwareInterface::registerFaceImage(void *img_ptr,
6241                                                  cam_pp_offline_src_config_t *config,
6242                                                  int32_t &faceID)
6243 {
6244     int rc = NO_ERROR;
6245     faceID = -1;
6246 
6247     if (img_ptr == NULL || config == NULL) {
6248         LOGE("img_ptr or config is NULL");
6249         return BAD_VALUE;
6250     }
6251 
6252     // allocate ion memory for source image
6253     QCameraHeapMemory *imgBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
6254     if (imgBuf == NULL) {
6255         LOGE("Unable to new heap memory obj for image buf");
6256         return NO_MEMORY;
6257     }
6258 
6259     rc = imgBuf->allocate(1, config->input_buf_planes.plane_info.frame_len);
6260     if (rc < 0) {
6261         LOGE("Unable to allocate heap memory for image buf");
6262         delete imgBuf;
6263         return NO_MEMORY;
6264     }
6265 
6266     void *pBufPtr = imgBuf->getPtr(0);
6267     if (pBufPtr == NULL) {
6268         LOGE("image buf is NULL");
6269         imgBuf->deallocate();
6270         delete imgBuf;
6271         return NO_MEMORY;
6272     }
6273     memcpy(pBufPtr, img_ptr, config->input_buf_planes.plane_info.frame_len);
6274     //Do cache ops before sending for reprocess
6275     imgBuf->cacheOps(0, ION_IOC_CLEAN_INV_CACHES);
6276 
6277     cam_pp_feature_config_t pp_feature;
6278     memset(&pp_feature, 0, sizeof(cam_pp_feature_config_t));
6279     pp_feature.feature_mask = CAM_QCOM_FEATURE_REGISTER_FACE;
6280     QCameraReprocessChannel *pChannel =
6281         addOfflineReprocChannel(*config, pp_feature, NULL, NULL);
6282 
6283     if (pChannel == NULL) {
6284         LOGE("fail to add offline reprocess channel");
6285         imgBuf->deallocate();
6286         delete imgBuf;
6287         return UNKNOWN_ERROR;
6288     }
6289 
6290     rc = pChannel->start();
6291     if (rc != NO_ERROR) {
6292         LOGE("Cannot start reprocess channel");
6293         imgBuf->deallocate();
6294         delete imgBuf;
6295         delete pChannel;
6296         return rc;
6297     }
6298 
6299     ssize_t bufSize = imgBuf->getSize(0);
6300     if (BAD_INDEX != bufSize) {
6301         rc = pChannel->doReprocess(imgBuf->getFd(0), imgBuf->getPtr(0),
6302                 (size_t)bufSize, faceID);
6303     } else {
6304         LOGE("Failed to retrieve buffer size (bad index)");
6305         return UNKNOWN_ERROR;
6306     }
6307 
6308     // done with register face image, free imgbuf and delete reprocess channel
6309     imgBuf->deallocate();
6310     delete imgBuf;
6311     imgBuf = NULL;
6312     pChannel->stop();
6313     delete pChannel;
6314     pChannel = NULL;
6315 
6316     return rc;
6317 }
6318 
6319 /*===========================================================================
6320  * FUNCTION   : release
6321  *
6322  * DESCRIPTION: release camera resource impl
6323  *
6324  * PARAMETERS : none
6325  *
6326  * RETURN     : int32_t type of status
6327  *              NO_ERROR  -- success
6328  *              none-zero failure code
6329  *==========================================================================*/
release()6330 int QCamera2HardwareInterface::release()
6331 {
6332     // stop and delete all channels
6333     for (int i = 0; i <QCAMERA_CH_TYPE_MAX ; i++) {
6334         if (m_channels[i] != NULL) {
6335             stopChannel((qcamera_ch_type_enum_t)i);
6336             delChannel((qcamera_ch_type_enum_t)i);
6337         }
6338     }
6339 
6340     return NO_ERROR;
6341 }
6342 
6343 /*===========================================================================
6344  * FUNCTION   : dump
6345  *
6346  * DESCRIPTION: camera status dump impl
6347  *
6348  * PARAMETERS :
6349  *   @fd      : fd for the buffer to be dumped with camera status
6350  *
6351  * RETURN     : int32_t type of status
6352  *              NO_ERROR  -- success
6353  *              none-zero failure code
6354  *==========================================================================*/
dump(int fd)6355 int QCamera2HardwareInterface::dump(int fd)
6356 {
6357     dprintf(fd, "\n Camera HAL information Begin \n");
6358     dprintf(fd, "Camera ID: %d \n", mCameraId);
6359     dprintf(fd, "StoreMetaDataInFrame: %d \n", mStoreMetaDataInFrame);
6360     dprintf(fd, "\n Configuration: %s", mParameters.dump().string());
6361     dprintf(fd, "\n State Information: %s", m_stateMachine.dump().string());
6362     dprintf(fd, "\n Camera HAL information End \n");
6363 
6364     /* send UPDATE_DEBUG_LEVEL to the backend so that they can read the
6365        debug level property */
6366     mParameters.updateDebugLevel();
6367     return NO_ERROR;
6368 }
6369 
6370 /*===========================================================================
6371  * FUNCTION   : processAPI
6372  *
6373  * DESCRIPTION: process API calls from upper layer
6374  *
6375  * PARAMETERS :
6376  *   @api         : API to be processed
6377  *   @api_payload : ptr to API payload if any
6378  *
6379  * RETURN     : int32_t type of status
6380  *              NO_ERROR  -- success
6381  *              none-zero failure code
6382  *==========================================================================*/
processAPI(qcamera_sm_evt_enum_t api,void * api_payload)6383 int QCamera2HardwareInterface::processAPI(qcamera_sm_evt_enum_t api, void *api_payload)
6384 {
6385     int ret = DEAD_OBJECT;
6386 
6387     if (m_smThreadActive) {
6388         ret = m_stateMachine.procAPI(api, api_payload);
6389     }
6390 
6391     return ret;
6392 }
6393 
6394 /*===========================================================================
6395  * FUNCTION   : processEvt
6396  *
6397  * DESCRIPTION: process Evt from backend via mm-camera-interface
6398  *
6399  * PARAMETERS :
6400  *   @evt         : event type to be processed
6401  *   @evt_payload : ptr to event payload if any
6402  *
6403  * RETURN     : int32_t type of status
6404  *              NO_ERROR  -- success
6405  *              none-zero failure code
6406  *==========================================================================*/
processEvt(qcamera_sm_evt_enum_t evt,void * evt_payload)6407 int QCamera2HardwareInterface::processEvt(qcamera_sm_evt_enum_t evt, void *evt_payload)
6408 {
6409     return m_stateMachine.procEvt(evt, evt_payload);
6410 }
6411 
6412 /*===========================================================================
6413  * FUNCTION   : processSyncEvt
6414  *
6415  * DESCRIPTION: process synchronous Evt from backend
6416  *
6417  * PARAMETERS :
6418  *   @evt         : event type to be processed
6419  *   @evt_payload : ptr to event payload if any
6420  *
6421  * RETURN     : int32_t type of status
6422  *              NO_ERROR  -- success
6423  *              none-zero failure code
6424  *==========================================================================*/
processSyncEvt(qcamera_sm_evt_enum_t evt,void * evt_payload)6425 int QCamera2HardwareInterface::processSyncEvt(qcamera_sm_evt_enum_t evt, void *evt_payload)
6426 {
6427     int rc = NO_ERROR;
6428 
6429     pthread_mutex_lock(&m_evtLock);
6430     rc =  processEvt(evt, evt_payload);
6431     if (rc == NO_ERROR) {
6432         memset(&m_evtResult, 0, sizeof(qcamera_api_result_t));
6433         while (m_evtResult.request_api != evt) {
6434             pthread_cond_wait(&m_evtCond, &m_evtLock);
6435         }
6436         rc =  m_evtResult.status;
6437     }
6438     pthread_mutex_unlock(&m_evtLock);
6439 
6440     return rc;
6441 }
6442 
6443 /*===========================================================================
6444  * FUNCTION   : evtHandle
6445  *
6446  * DESCRIPTION: Function registerd to mm-camera-interface to handle backend events
6447  *
6448  * PARAMETERS :
6449  *   @camera_handle : event type to be processed
6450  *   @evt           : ptr to event
6451  *   @user_data     : user data ptr
6452  *
6453  * RETURN     : none
6454  *==========================================================================*/
camEvtHandle(uint32_t,mm_camera_event_t * evt,void * user_data)6455 void QCamera2HardwareInterface::camEvtHandle(uint32_t /*camera_handle*/,
6456                                           mm_camera_event_t *evt,
6457                                           void *user_data)
6458 {
6459     QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)user_data;
6460     if (obj && evt) {
6461         mm_camera_event_t *payload =
6462             (mm_camera_event_t *)malloc(sizeof(mm_camera_event_t));
6463         if (NULL != payload) {
6464             *payload = *evt;
6465             //peek into the event, if this is an eztune event from server,
6466             //then we don't need to post it to the SM Qs, we shud directly
6467             //spawn a thread and get the job done (jpeg or raw snapshot)
6468             switch (payload->server_event_type) {
6469                 case CAM_EVENT_TYPE_INT_TAKE_JPEG:
6470                     //Received JPEG trigger from eztune
6471                     if (false == obj->m_bIntJpegEvtPending) {
6472                         pthread_mutex_lock(&obj->m_int_lock);
6473                         obj->m_bIntJpegEvtPending = true;
6474                         pthread_mutex_unlock(&obj->m_int_lock);
6475                         obj->takePictureInternal();
6476                     }
6477                     free(payload);
6478                     break;
6479                 case CAM_EVENT_TYPE_INT_TAKE_RAW:
6480                     //Received RAW trigger from eztune
6481                     if (false == obj->m_bIntRawEvtPending) {
6482                         pthread_mutex_lock(&obj->m_int_lock);
6483                         obj->m_bIntRawEvtPending = true;
6484                         pthread_mutex_unlock(&obj->m_int_lock);
6485                         obj->takePictureInternal();
6486                     }
6487                     free(payload);
6488                     break;
6489                 case CAM_EVENT_TYPE_DAEMON_DIED:
6490                     {
6491                         Mutex::Autolock l(obj->mDefLock);
6492                         obj->mDefCond.broadcast();
6493                         LOGH("broadcast mDefCond signal\n");
6494                     }
6495                 default:
6496                     obj->processEvt(QCAMERA_SM_EVT_EVT_NOTIFY, payload);
6497                     break;
6498             }
6499         }
6500     } else {
6501         LOGE("NULL user_data");
6502     }
6503 }
6504 
6505 /*===========================================================================
6506  * FUNCTION   : jpegEvtHandle
6507  *
6508  * DESCRIPTION: Function registerd to mm-jpeg-interface to handle jpeg events
6509  *
6510  * PARAMETERS :
6511  *   @status    : status of jpeg job
6512  *   @client_hdl: jpeg client handle
6513  *   @jobId     : jpeg job Id
6514  *   @p_ouput   : ptr to jpeg output result struct
6515  *   @userdata  : user data ptr
6516  *
6517  * RETURN     : none
6518  *==========================================================================*/
jpegEvtHandle(jpeg_job_status_t status,uint32_t,uint32_t jobId,mm_jpeg_output_t * p_output,void * userdata)6519 void QCamera2HardwareInterface::jpegEvtHandle(jpeg_job_status_t status,
6520                                               uint32_t /*client_hdl*/,
6521                                               uint32_t jobId,
6522                                               mm_jpeg_output_t *p_output,
6523                                               void *userdata)
6524 {
6525     QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)userdata;
6526     if (obj) {
6527         qcamera_jpeg_evt_payload_t *payload =
6528             (qcamera_jpeg_evt_payload_t *)malloc(sizeof(qcamera_jpeg_evt_payload_t));
6529         if (NULL != payload) {
6530             memset(payload, 0, sizeof(qcamera_jpeg_evt_payload_t));
6531             payload->status = status;
6532             payload->jobId = jobId;
6533             if (p_output != NULL) {
6534                 payload->out_data = *p_output;
6535             }
6536             obj->processEvt(QCAMERA_SM_EVT_JPEG_EVT_NOTIFY, payload);
6537         }
6538     } else {
6539         LOGE("NULL user_data");
6540     }
6541 }
6542 
6543 /*===========================================================================
6544  * FUNCTION   : thermalEvtHandle
6545  *
6546  * DESCRIPTION: routine to handle thermal event notification
6547  *
6548  * PARAMETERS :
6549  *   @level      : thermal level
6550  *   @userdata   : userdata passed in during registration
6551  *   @data       : opaque data from thermal client
6552  *
6553  * RETURN     : int32_t type of status
6554  *              NO_ERROR  -- success
6555  *              none-zero failure code
6556  *==========================================================================*/
thermalEvtHandle(qcamera_thermal_level_enum_t * level,void * userdata,void * data)6557 int QCamera2HardwareInterface::thermalEvtHandle(
6558         qcamera_thermal_level_enum_t *level, void *userdata, void *data)
6559 {
6560     if (!mCameraOpened) {
6561         LOGH("Camera is not opened, no need to handle thermal evt");
6562         return NO_ERROR;
6563     }
6564 
6565     // Make sure thermal events are logged
6566     LOGH("level = %d, userdata = %p, data = %p",
6567          *level, userdata, data);
6568     //We don't need to lockAPI, waitAPI here. QCAMERA_SM_EVT_THERMAL_NOTIFY
6569     // becomes an aync call. This also means we can only pass payload
6570     // by value, not by address.
6571     return processAPI(QCAMERA_SM_EVT_THERMAL_NOTIFY, (void *)level);
6572 }
6573 
6574 /*===========================================================================
6575  * FUNCTION   : sendEvtNotify
6576  *
6577  * DESCRIPTION: send event notify to notify thread
6578  *
6579  * PARAMETERS :
6580  *   @msg_type: msg type to be sent
6581  *   @ext1    : optional extension1
6582  *   @ext2    : optional extension2
6583  *
6584  * RETURN     : int32_t type of status
6585  *              NO_ERROR  -- success
6586  *              none-zero failure code
6587  *==========================================================================*/
sendEvtNotify(int32_t msg_type,int32_t ext1,int32_t ext2)6588 int32_t QCamera2HardwareInterface::sendEvtNotify(int32_t msg_type,
6589                                                  int32_t ext1,
6590                                                  int32_t ext2)
6591 {
6592     qcamera_callback_argm_t cbArg;
6593     memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
6594     cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK;
6595     cbArg.msg_type = msg_type;
6596     cbArg.ext1 = ext1;
6597     cbArg.ext2 = ext2;
6598     return m_cbNotifier.notifyCallback(cbArg);
6599 }
6600 
6601 /*===========================================================================
6602  * FUNCTION   : processAEInfo
6603  *
6604  * DESCRIPTION: process AE updates
6605  *
6606  * PARAMETERS :
6607  *   @ae_params: current AE parameters
6608  *
6609  * RETURN     : None
6610  *==========================================================================*/
processAEInfo(cam_3a_params_t & ae_params)6611 int32_t QCamera2HardwareInterface::processAEInfo(cam_3a_params_t &ae_params)
6612 {
6613     mParameters.updateAEInfo(ae_params);
6614     if (mParameters.isInstantAECEnabled()) {
6615         // Reset Instant AEC info only if instant aec enabled.
6616         bool bResetInstantAec = false;
6617         if (ae_params.settled) {
6618             // If AEC settled, reset instant AEC
6619             bResetInstantAec = true;
6620         } else if ((mParameters.isInstantCaptureEnabled()) &&
6621                 (mInstantAecFrameCount >= mParameters.getAecFrameBoundValue())) {
6622             // if AEC not settled, and instant capture enabled,
6623             // reset instant AEC only when frame count is
6624             // more or equal to AEC frame bound value.
6625             bResetInstantAec = true;
6626         } else if ((mParameters.isInstantAECEnabled()) &&
6627                 (mInstantAecFrameCount >= mParameters.getAecSkipDisplayFrameBound())) {
6628             // if AEC not settled, and only instant AEC enabled,
6629             // reset instant AEC only when frame count is
6630             // more or equal to AEC skip display frame bound value.
6631             bResetInstantAec = true;
6632         }
6633 
6634         if (bResetInstantAec) {
6635             LOGD("setting instant AEC to false");
6636             mParameters.setInstantAEC(false, true);
6637             mInstantAecFrameCount = 0;
6638         }
6639     }
6640     return NO_ERROR;
6641 }
6642 
6643 /*===========================================================================
6644  * FUNCTION   : processFocusPositionInfo
6645  *
6646  * DESCRIPTION: process AF updates
6647  *
6648  * PARAMETERS :
6649  *   @cur_pos_info: current lens position
6650  *
6651  * RETURN     : None
6652  *==========================================================================*/
processFocusPositionInfo(cam_focus_pos_info_t & cur_pos_info)6653 int32_t QCamera2HardwareInterface::processFocusPositionInfo(cam_focus_pos_info_t &cur_pos_info)
6654 {
6655     mParameters.updateCurrentFocusPosition(cur_pos_info);
6656     return NO_ERROR;
6657 }
6658 
6659 /*===========================================================================
6660  * FUNCTION   : processAutoFocusEvent
6661  *
6662  * DESCRIPTION: process auto focus event
6663  *
6664  * PARAMETERS :
6665  *   @focus_data: struct containing auto focus result info
6666  *
6667  * RETURN     : int32_t type of status
6668  *              NO_ERROR  -- success
6669  *              none-zero failure code
6670  *==========================================================================*/
processAutoFocusEvent(cam_auto_focus_data_t & focus_data)6671 int32_t QCamera2HardwareInterface::processAutoFocusEvent(cam_auto_focus_data_t &focus_data)
6672 {
6673     int32_t ret = NO_ERROR;
6674     LOGH("E");
6675 
6676     if (getRelatedCamSyncInfo()->mode == CAM_MODE_SECONDARY) {
6677         // Ignore focus updates
6678         LOGH("X Secondary Camera, no need to process!! ");
6679         return ret;
6680     }
6681     cam_focus_mode_type focusMode = mParameters.getFocusMode();
6682     LOGH("[AF_DBG]  focusMode=%d, focusState=%d isDepth=%d",
6683              focusMode, focus_data.focus_state, focus_data.isDepth);
6684 
6685     switch (focusMode) {
6686     case CAM_FOCUS_MODE_AUTO:
6687     case CAM_FOCUS_MODE_MACRO:
6688         // ignore AF event if AF was already cancelled meanwhile
6689         if (!mActiveAF) {
6690             break;
6691         }
6692         // If the HAL focus mode is different from AF INFINITY focus mode, send event to app
6693         if ((focus_data.focus_mode == CAM_FOCUS_MODE_INFINITY) &&
6694                 (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) {
6695             ret = sendEvtNotify(CAMERA_MSG_FOCUS, true, 0);
6696             mActiveAF = false; // reset the mActiveAF in this special case
6697             break;
6698         }
6699 
6700         //while transitioning from CAF->Auto/Macro, we might receive CAF related
6701         //events (PASSIVE_*) due to timing. Ignore such events if any.
6702         if ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN) ||
6703                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
6704                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED)) {
6705             break;
6706         }
6707 
6708         //This is just an intermediate update to HAL indicating focus is in progress. No need
6709         //to send this event to app. Same applies to INACTIVE state as well.
6710         if ((focus_data.focus_state == CAM_AF_STATE_ACTIVE_SCAN) ||
6711                 (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) {
6712             break;
6713         }
6714         // update focus distance
6715         mParameters.updateFocusDistances(&focus_data.focus_dist);
6716 
6717         //flush any old snapshot frames in ZSL Q which are not focused.
6718         if (mParameters.isZSLMode() && focus_data.flush_info.needFlush ) {
6719             QCameraPicChannel *pZSLChannel =
6720                     (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
6721             if (NULL != pZSLChannel) {
6722                 //flush the zsl-buffer
6723                 uint32_t flush_frame_idx = focus_data.flush_info.focused_frame_idx;
6724                 LOGD("flush the zsl-buffer before frame = %u.", flush_frame_idx);
6725                 pZSLChannel->flushSuperbuffer(flush_frame_idx);
6726             }
6727         }
6728 
6729         //send event to app finally
6730         LOGI("Send AF DOne event to app");
6731         ret = sendEvtNotify(CAMERA_MSG_FOCUS,
6732                             (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED), 0);
6733         break;
6734     case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
6735     case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
6736 
6737         // If the HAL focus mode is different from AF INFINITY focus mode, send event to app
6738         if ((focus_data.focus_mode == CAM_FOCUS_MODE_INFINITY) &&
6739                 (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) {
6740             ret = sendEvtNotify(CAMERA_MSG_FOCUS, false, 0);
6741             mActiveAF = false; // reset the mActiveAF in this special case
6742             break;
6743         }
6744 
6745         //If AutoFocus() is triggered while in CAF mode, ignore all CAF events (PASSIVE_*) and
6746         //process/wait for only ACTIVE_* events.
6747         if (((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
6748                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED) ||
6749                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN)) && mActiveAF) {
6750             break;
6751         }
6752 
6753         if (!bDepthAFCallbacks && focus_data.isDepth &&
6754                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN)) {
6755             LOGD("Skip sending scan state to app, if depth focus");
6756             break;
6757         }
6758 
6759         //These are the AF states for which we need to send notification to app in CAF mode.
6760         //This includes both regular CAF (PASSIVE) events as well as ACTIVE events ( in case
6761         //AF is triggered while in CAF mode)
6762         if ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
6763                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED) ||
6764                 (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED) ||
6765                 (focus_data.focus_state == CAM_AF_STATE_NOT_FOCUSED_LOCKED)) {
6766 
6767             // update focus distance
6768             mParameters.updateFocusDistances(&focus_data.focus_dist);
6769 
6770             if (mParameters.isZSLMode() && focus_data.flush_info.needFlush ) {
6771                 QCameraPicChannel *pZSLChannel =
6772                         (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
6773                 if (NULL != pZSLChannel) {
6774                     //flush the zsl-buffer
6775                     uint32_t flush_frame_idx = focus_data.flush_info.focused_frame_idx;
6776                     LOGD("flush the zsl-buffer before frame = %u.", flush_frame_idx);
6777                     pZSLChannel->flushSuperbuffer(flush_frame_idx);
6778                 }
6779             }
6780 
6781             if (mActiveAF) {
6782                 LOGI("Send AF Done event to app");
6783             }
6784             ret = sendEvtNotify(CAMERA_MSG_FOCUS,
6785                     ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
6786                     (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED)), 0);
6787         }
6788         ret = sendEvtNotify(CAMERA_MSG_FOCUS_MOVE,
6789                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN), 0);
6790         break;
6791     case CAM_FOCUS_MODE_INFINITY:
6792     case CAM_FOCUS_MODE_FIXED:
6793     case CAM_FOCUS_MODE_EDOF:
6794     default:
6795         LOGH("no ops for autofocus event in focusmode %d", focusMode);
6796         break;
6797     }
6798 
6799     //Reset mActiveAF once we receive focus done event
6800     if ((focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED) ||
6801             (focus_data.focus_state == CAM_AF_STATE_NOT_FOCUSED_LOCKED)) {
6802         mActiveAF = false;
6803     }
6804 
6805     LOGH("X");
6806     return ret;
6807 }
6808 
6809 /*===========================================================================
6810  * FUNCTION   : processZoomEvent
6811  *
6812  * DESCRIPTION: process zoom event
6813  *
6814  * PARAMETERS :
6815  *   @crop_info : crop info as a result of zoom operation
6816  *
6817  * RETURN     : int32_t type of status
6818  *              NO_ERROR  -- success
6819  *              none-zero failure code
6820  *==========================================================================*/
processZoomEvent(cam_crop_data_t & crop_info)6821 int32_t QCamera2HardwareInterface::processZoomEvent(cam_crop_data_t &crop_info)
6822 {
6823     int32_t ret = NO_ERROR;
6824 
6825     for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
6826         if (m_channels[i] != NULL) {
6827             ret = m_channels[i]->processZoomDone(mPreviewWindow, crop_info);
6828         }
6829     }
6830     return ret;
6831 }
6832 
6833 /*===========================================================================
6834  * FUNCTION   : processZSLCaptureDone
6835  *
6836  * DESCRIPTION: process ZSL capture done events
6837  *
6838  * PARAMETERS : None
6839  *
6840  * RETURN     : int32_t type of status
6841  *              NO_ERROR  -- success
6842  *              none-zero failure code
6843  *==========================================================================*/
processZSLCaptureDone()6844 int32_t QCamera2HardwareInterface::processZSLCaptureDone()
6845 {
6846     int rc = NO_ERROR;
6847 
6848     if (++mInputCount >= mParameters.getBurstCountForAdvancedCapture()) {
6849         rc = unconfigureAdvancedCapture();
6850     }
6851 
6852     return rc;
6853 }
6854 
6855 /*===========================================================================
6856  * FUNCTION   : processRetroAECUnlock
6857  *
6858  * DESCRIPTION: process retro burst AEC unlock events
6859  *
6860  * PARAMETERS : None
6861  *
6862  * RETURN     : int32_t type of status
6863  *              NO_ERROR  -- success
6864  *              none-zero failure code
6865  *==========================================================================*/
processRetroAECUnlock()6866 int32_t QCamera2HardwareInterface::processRetroAECUnlock()
6867 {
6868     int rc = NO_ERROR;
6869 
6870     LOGH("LED assisted AF Release AEC Lock");
6871     rc = mParameters.setAecLock("false");
6872     if (NO_ERROR != rc) {
6873         LOGE("Error setting AEC lock");
6874         return rc;
6875     }
6876 
6877     rc = mParameters.commitParameters();
6878     if (NO_ERROR != rc) {
6879         LOGE("Error during camera parameter commit");
6880     } else {
6881         m_bLedAfAecLock = FALSE;
6882     }
6883 
6884     return rc;
6885 }
6886 
6887 /*===========================================================================
6888  * FUNCTION   : processHDRData
6889  *
6890  * DESCRIPTION: process HDR scene events
6891  *
6892  * PARAMETERS :
6893  *   @hdr_scene : HDR scene event data
6894  *
6895  * RETURN     : int32_t type of status
6896  *              NO_ERROR  -- success
6897  *              none-zero failure code
6898  *==========================================================================*/
processHDRData(__unused cam_asd_hdr_scene_data_t hdr_scene)6899 int32_t QCamera2HardwareInterface::processHDRData(
6900         __unused cam_asd_hdr_scene_data_t hdr_scene)
6901 {
6902     int rc = NO_ERROR;
6903 
6904 #ifndef VANILLA_HAL
6905     if (hdr_scene.is_hdr_scene &&
6906       (hdr_scene.hdr_confidence > HDR_CONFIDENCE_THRESHOLD) &&
6907       mParameters.isAutoHDREnabled()) {
6908         m_HDRSceneEnabled = true;
6909     } else {
6910         m_HDRSceneEnabled = false;
6911     }
6912     mParameters.setHDRSceneEnable(m_HDRSceneEnabled);
6913 
6914     if ( msgTypeEnabled(CAMERA_MSG_META_DATA) ) {
6915 
6916         size_t data_len = sizeof(int);
6917         size_t buffer_len = 1 *sizeof(int)       //meta type
6918                           + 1 *sizeof(int)       //data len
6919                           + 1 *sizeof(int);      //data
6920         camera_memory_t *hdrBuffer = mGetMemory(-1,
6921                                                  buffer_len,
6922                                                  1,
6923                                                  mCallbackCookie);
6924         if ( NULL == hdrBuffer ) {
6925             LOGE("Not enough memory for auto HDR data");
6926             return NO_MEMORY;
6927         }
6928 
6929         int *pHDRData = (int *)hdrBuffer->data;
6930         if (pHDRData == NULL) {
6931             LOGE("memory data ptr is NULL");
6932             return UNKNOWN_ERROR;
6933         }
6934 
6935         pHDRData[0] = CAMERA_META_DATA_HDR;
6936         pHDRData[1] = (int)data_len;
6937         pHDRData[2] = m_HDRSceneEnabled;
6938 
6939         qcamera_callback_argm_t cbArg;
6940         memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
6941         cbArg.cb_type = QCAMERA_DATA_CALLBACK;
6942         cbArg.msg_type = CAMERA_MSG_META_DATA;
6943         cbArg.data = hdrBuffer;
6944         cbArg.user_data = hdrBuffer;
6945         cbArg.cookie = this;
6946         cbArg.release_cb = releaseCameraMemory;
6947         rc = m_cbNotifier.notifyCallback(cbArg);
6948         if (rc != NO_ERROR) {
6949             LOGE("fail sending auto HDR notification");
6950             hdrBuffer->release(hdrBuffer);
6951         }
6952     }
6953 
6954     LOGH("hdr_scene_data: processHDRData: %d %f",
6955           hdr_scene.is_hdr_scene,
6956           hdr_scene.hdr_confidence);
6957 
6958 #endif
6959   return rc;
6960 }
6961 
6962 /*===========================================================================
6963  * FUNCTION   : processLEDCalibration
6964  *
6965  * DESCRIPTION: process LED calibration result
6966  *
6967  * PARAMETERS :
6968  *   @value : Calibaration result
6969  *
6970  * RETURN     : int32_t type of status
6971  *              NO_ERROR  -- success
6972  *              none-zero failure code
6973  *==========================================================================*/
processLEDCalibration(int32_t value)6974 int32_t QCamera2HardwareInterface::processLEDCalibration(int32_t value)
6975 {
6976     int32_t rc = NO_ERROR;
6977 #ifndef VANILLA_HAL
6978     if (mParameters.getDualLedCalibration()) {
6979         LOGH("Dual LED calibration value = %d", value);
6980         int32_t data_len = sizeof(value);
6981         int32_t buffer_len = sizeof(int)       //meta type
6982                 + sizeof(int)                  //data len
6983                 + data_len;                    //data
6984         camera_memory_t *buffer = mGetMemory(-1,
6985                 buffer_len, 1, mCallbackCookie);
6986         if ( NULL == buffer ) {
6987             LOGE("Not enough memory for data");
6988             return NO_MEMORY;
6989         }
6990 
6991         int *pData = (int *)buffer->data;
6992         if (pData == NULL) {
6993             LOGE("memory data ptr is NULL");
6994             buffer->release(buffer);
6995             return UNKNOWN_ERROR;
6996         }
6997 
6998         pData[0] = QCAMERA_METADATA_LED_CALIB;
6999         pData[1] = (int)data_len;
7000         pData[2] = value;
7001 
7002         qcamera_callback_argm_t cbArg;
7003         memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
7004         cbArg.cb_type = QCAMERA_DATA_CALLBACK;
7005         cbArg.msg_type = CAMERA_MSG_META_DATA;
7006         cbArg.data = buffer;
7007         cbArg.user_data = buffer;
7008         cbArg.cookie = this;
7009         cbArg.release_cb = releaseCameraMemory;
7010         int32_t rc = m_cbNotifier.notifyCallback(cbArg);
7011         if (rc != NO_ERROR) {
7012             LOGE("fail sending notification");
7013             buffer->release(buffer);
7014         }
7015     }
7016 #else
7017     (void)value;  // unused
7018 #endif
7019     return rc;
7020 }
7021 
7022 
7023 /*===========================================================================
7024  * FUNCTION   : transAwbMetaToParams
7025  *
7026  * DESCRIPTION: translate awb params from metadata callback to QCameraParametersIntf
7027  *
7028  * PARAMETERS :
7029  *   @awb_params : awb params from metadata callback
7030  *
7031  * RETURN     : int32_t type of status
7032  *              NO_ERROR  -- success
7033  *              none-zero failure code
7034  *==========================================================================*/
transAwbMetaToParams(cam_awb_params_t & awb_params)7035 int32_t QCamera2HardwareInterface::transAwbMetaToParams(cam_awb_params_t &awb_params)
7036 {
7037     mParameters.updateAWBParams(awb_params);
7038     return NO_ERROR;
7039 }
7040 
7041 /*===========================================================================
7042  * FUNCTION   : processPrepSnapshotDone
7043  *
7044  * DESCRIPTION: process prep snapshot done event
7045  *
7046  * PARAMETERS :
7047  *   @prep_snapshot_state  : state of prepare snapshot done. In other words,
7048  *                           i.e. whether need future frames for capture.
7049  *
7050  * RETURN     : int32_t type of status
7051  *              NO_ERROR  -- success
7052  *              none-zero failure code
7053  *==========================================================================*/
processPrepSnapshotDoneEvent(cam_prep_snapshot_state_t prep_snapshot_state)7054 int32_t QCamera2HardwareInterface::processPrepSnapshotDoneEvent(
7055                         cam_prep_snapshot_state_t prep_snapshot_state)
7056 {
7057     int32_t ret = NO_ERROR;
7058     LOGI("[KPI Perf]: Received PREPARE SANSPHOT Done event state = %d",
7059             prep_snapshot_state);
7060     if (m_channels[QCAMERA_CH_TYPE_ZSL] &&
7061         prep_snapshot_state == NEED_FUTURE_FRAME) {
7062         LOGH("already handled in mm-camera-intf, no ops here");
7063         if (isRetroPicture()) {
7064             mParameters.setAecLock("true");
7065             mParameters.commitParameters();
7066             m_bLedAfAecLock = TRUE;
7067         }
7068     }
7069     return ret;
7070 }
7071 
7072 /*===========================================================================
7073  * FUNCTION   : processASDUpdate
7074  *
7075  * DESCRIPTION: process ASD update event
7076  *
7077  * PARAMETERS :
7078  *   @scene: selected scene mode
7079  *
7080  * RETURN     : int32_t type of status
7081  *              NO_ERROR  -- success
7082  *              none-zero failure code
7083  *==========================================================================*/
processASDUpdate(__unused cam_asd_decision_t asd_decision)7084 int32_t QCamera2HardwareInterface::processASDUpdate(
7085         __unused cam_asd_decision_t asd_decision)
7086 {
7087 #ifndef VANILLA_HAL
7088     if ( msgTypeEnabled(CAMERA_MSG_META_DATA) ) {
7089         size_t data_len = sizeof(cam_auto_scene_t);
7090         size_t buffer_len = 1 *sizeof(int)       //meta type
7091                 + 1 *sizeof(int)       //data len
7092                 + data_len;            //data
7093         camera_memory_t *asdBuffer = mGetMemory(-1,
7094                 buffer_len, 1, mCallbackCookie);
7095         if ( NULL == asdBuffer ) {
7096             LOGE("Not enough memory for histogram data");
7097             return NO_MEMORY;
7098         }
7099 
7100         int *pASDData = (int *)asdBuffer->data;
7101         if (pASDData == NULL) {
7102             LOGE("memory data ptr is NULL");
7103             return UNKNOWN_ERROR;
7104         }
7105 
7106         pASDData[0] = CAMERA_META_DATA_ASD;
7107         pASDData[1] = (int)data_len;
7108         pASDData[2] = asd_decision.detected_scene;
7109 
7110         qcamera_callback_argm_t cbArg;
7111         memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
7112         cbArg.cb_type = QCAMERA_DATA_CALLBACK;
7113         cbArg.msg_type = CAMERA_MSG_META_DATA;
7114         cbArg.data = asdBuffer;
7115         cbArg.user_data = asdBuffer;
7116         cbArg.cookie = this;
7117         cbArg.release_cb = releaseCameraMemory;
7118         int32_t rc = m_cbNotifier.notifyCallback(cbArg);
7119         if (rc != NO_ERROR) {
7120             LOGE("fail sending notification");
7121             asdBuffer->release(asdBuffer);
7122         }
7123     }
7124 #endif
7125     return NO_ERROR;
7126 }
7127 
7128 /*===========================================================================
7129  * FUNCTION   : processJpegNotify
7130  *
7131  * DESCRIPTION: process jpeg event
7132  *
7133  * PARAMETERS :
7134  *   @jpeg_evt: ptr to jpeg event payload
7135  *
7136  * RETURN     : int32_t type of status
7137  *              NO_ERROR  -- success
7138  *              none-zero failure code
7139  *==========================================================================*/
processJpegNotify(qcamera_jpeg_evt_payload_t * jpeg_evt)7140 int32_t QCamera2HardwareInterface::processJpegNotify(qcamera_jpeg_evt_payload_t *jpeg_evt)
7141 {
7142     return m_postprocessor.processJpegEvt(jpeg_evt);
7143 }
7144 
7145 
7146 /*===========================================================================
7147  * FUNCTION   : processDualCamFovControl
7148  *
7149  * DESCRIPTION: Based on the result collected from FOV control-
7150  *              1. Switch the master camera if needed
7151  *              2. Toggle the Low Power Mode for slave camera
7152  *
7153  * PARAMETERS : none
7154  *
7155  * RETURN     : none
7156  *==========================================================================*/
processDualCamFovControl()7157 void QCamera2HardwareInterface::processDualCamFovControl()
7158 {
7159    uint32_t activeCameras;
7160    bool bundledSnapshot;
7161    fov_control_result_t fovControlResult;
7162    cam_sync_type_t camMasterSnapshot;
7163 
7164     if (!isDualCamera()) {
7165         return;
7166     }
7167 
7168     fovControlResult = m_pFovControl->getFovControlResult();
7169 
7170     if (fovControlResult.isValid) {
7171         activeCameras = fovControlResult.activeCameras;
7172         bundledSnapshot = fovControlResult.snapshotPostProcess;
7173         camMasterSnapshot = fovControlResult.camMasterPreview;
7174 
7175         processCameraControl(activeCameras, bundledSnapshot);
7176         switchCameraCb(fovControlResult.camMasterPreview);
7177     }
7178 }
7179 
7180 /*===========================================================================
7181  * FUNCTION   : processCameraControl
7182  *
7183  * DESCRIPTION: Suspend and resume camera
7184  *
7185  * PARAMETERS :
7186  *
7187  * RETURN     : int32_t type of status
7188  *              NO_ERROR  -- success
7189  *              none-zero failure code
7190  *==========================================================================*/
processCameraControl(uint32_t activeCameras,bool bundledSnapshot)7191 int32_t QCamera2HardwareInterface::processCameraControl(
7192         uint32_t activeCameras,
7193         bool     bundledSnapshot)
7194 {
7195     int32_t ret = NO_ERROR;
7196 
7197     //Update camera status to internal channel
7198     for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
7199         if (m_channels[i] != NULL && m_channels[i]->isDualChannel()) {
7200             ret = m_channels[i]->processCameraControl(activeCameras, bundledSnapshot);
7201             if (ret != NO_ERROR) {
7202                 LOGE("Channel Switch Failed");
7203                 break;
7204             }
7205         }
7206     }
7207 
7208     if ((activeCameras != mActiveCameras) ||
7209             ((activeCameras == MM_CAMERA_DUAL_CAM) && (bundledSnapshot != mBundledSnapshot))) {
7210 
7211         if (activeCameras != mActiveCameras) {
7212             //Set camera controls to parameter and back-end
7213             ret = mParameters.setCameraControls(activeCameras);
7214         }
7215 
7216         mParameters.setBundledSnapshot(bundledSnapshot);
7217         mParameters.setNumOfSnapshot();
7218 
7219         LOGH("mActiveCameras = %d to %d, bundledSnapshot = %d to %d",
7220                 mActiveCameras, activeCameras, mBundledSnapshot, bundledSnapshot);
7221         mActiveCameras   = activeCameras;
7222         mBundledSnapshot = bundledSnapshot;
7223     }
7224 
7225     return ret;
7226 }
7227 
7228 /*===========================================================================
7229  * FUNCTION   : switchCameraCb
7230  *
7231  * DESCRIPTION: switch camera's in case of dual camera
7232  *
7233  * PARAMETERS :
7234  * @camMaster : Master camera
7235  *
7236  * RETURN     : int32_t type of status
7237  *              NO_ERROR  -- success
7238  *              none-zero failure code
7239  *==========================================================================*/
switchCameraCb(uint32_t camMaster)7240 int32_t QCamera2HardwareInterface::switchCameraCb(uint32_t camMaster)
7241 {
7242     int32_t ret = NO_ERROR;
7243 
7244     if (mActiveCameras & camMaster) {
7245         for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
7246             if (m_channels[i] != NULL && m_channels[i]->isDualChannel()) {
7247                 ret = m_channels[i]->switchChannelCb(camMaster);
7248                 if (ret != NO_ERROR) {
7249                     LOGE("Channel Switch Failed");
7250                     break;
7251                 }
7252             }
7253         }
7254 
7255         if (mMasterCamera != camMaster) {
7256             if (ret == NO_ERROR) {
7257                 //Trigger Event to modules to update Master info
7258                 mParameters.setSwitchCamera(camMaster);
7259             }
7260         }
7261         // Update master camera
7262         mMasterCamera = camMaster;
7263     }
7264 
7265     return ret;
7266 }
7267 
7268 /*===========================================================================
7269  * FUNCTION   : lockAPI
7270  *
7271  * DESCRIPTION: lock to process API
7272  *
7273  * PARAMETERS : none
7274  *
7275  * RETURN     : none
7276  *==========================================================================*/
lockAPI()7277 void QCamera2HardwareInterface::lockAPI()
7278 {
7279     pthread_mutex_lock(&m_lock);
7280 }
7281 
7282 /*===========================================================================
7283  * FUNCTION   : waitAPIResult
7284  *
7285  * DESCRIPTION: wait for API result coming back. This is a blocking call, it will
7286  *              return only cerntain API event type arrives
7287  *
7288  * PARAMETERS :
7289  *   @api_evt : API event type
7290  *
7291  * RETURN     : none
7292  *==========================================================================*/
waitAPIResult(qcamera_sm_evt_enum_t api_evt,qcamera_api_result_t * apiResult)7293 void QCamera2HardwareInterface::waitAPIResult(qcamera_sm_evt_enum_t api_evt,
7294         qcamera_api_result_t *apiResult)
7295 {
7296     LOGD("wait for API result of evt (%d)", api_evt);
7297     int resultReceived = 0;
7298     while  (!resultReceived) {
7299         pthread_cond_wait(&m_cond, &m_lock);
7300         if (m_apiResultList != NULL) {
7301             api_result_list *apiResultList = m_apiResultList;
7302             api_result_list *apiResultListPrevious = m_apiResultList;
7303             while (apiResultList != NULL) {
7304                 if (apiResultList->result.request_api == api_evt) {
7305                     resultReceived = 1;
7306                     *apiResult = apiResultList->result;
7307                     apiResultListPrevious->next = apiResultList->next;
7308                     if (apiResultList == m_apiResultList) {
7309                         m_apiResultList = apiResultList->next;
7310                     }
7311                     free(apiResultList);
7312                     break;
7313                 }
7314                 else {
7315                     apiResultListPrevious = apiResultList;
7316                     apiResultList = apiResultList->next;
7317                 }
7318             }
7319         }
7320     }
7321     LOGD("return (%d) from API result wait for evt (%d)",
7322            apiResult->status, api_evt);
7323 }
7324 
7325 
7326 /*===========================================================================
7327  * FUNCTION   : unlockAPI
7328  *
7329  * DESCRIPTION: API processing is done, unlock
7330  *
7331  * PARAMETERS : none
7332  *
7333  * RETURN     : none
7334  *==========================================================================*/
unlockAPI()7335 void QCamera2HardwareInterface::unlockAPI()
7336 {
7337     pthread_mutex_unlock(&m_lock);
7338 }
7339 
7340 /*===========================================================================
7341  * FUNCTION   : signalAPIResult
7342  *
7343  * DESCRIPTION: signal condition viarable that cerntain API event type arrives
7344  *
7345  * PARAMETERS :
7346  *   @result  : API result
7347  *
7348  * RETURN     : none
7349  *==========================================================================*/
signalAPIResult(qcamera_api_result_t * result)7350 void QCamera2HardwareInterface::signalAPIResult(qcamera_api_result_t *result)
7351 {
7352 
7353     pthread_mutex_lock(&m_lock);
7354     api_result_list *apiResult = (api_result_list *)malloc(sizeof(api_result_list));
7355     if (apiResult == NULL) {
7356         LOGE("ERROR: malloc for api result failed, Result will not be sent");
7357         goto malloc_failed;
7358     }
7359     apiResult->result = *result;
7360     apiResult->next = NULL;
7361     if (m_apiResultList == NULL) m_apiResultList = apiResult;
7362     else {
7363         api_result_list *apiResultList = m_apiResultList;
7364         while(apiResultList->next != NULL) apiResultList = apiResultList->next;
7365         apiResultList->next = apiResult;
7366     }
7367 malloc_failed:
7368     pthread_cond_broadcast(&m_cond);
7369     pthread_mutex_unlock(&m_lock);
7370 }
7371 
7372 /*===========================================================================
7373  * FUNCTION   : signalEvtResult
7374  *
7375  * DESCRIPTION: signal condition variable that certain event was processed
7376  *
7377  * PARAMETERS :
7378  *   @result  : Event result
7379  *
7380  * RETURN     : none
7381  *==========================================================================*/
signalEvtResult(qcamera_api_result_t * result)7382 void QCamera2HardwareInterface::signalEvtResult(qcamera_api_result_t *result)
7383 {
7384     pthread_mutex_lock(&m_evtLock);
7385     m_evtResult = *result;
7386     pthread_cond_signal(&m_evtCond);
7387     pthread_mutex_unlock(&m_evtLock);
7388 }
7389 
prepareRawStream(QCameraChannel * curChannel)7390 int32_t QCamera2HardwareInterface::prepareRawStream(QCameraChannel *curChannel)
7391 {
7392     int32_t rc = NO_ERROR;
7393     cam_dimension_t str_dim,max_dim;
7394     QCameraChannel *pChannel;
7395 
7396     max_dim.width = 0;
7397     max_dim.height = 0;
7398 
7399     for (int j = 0; j < QCAMERA_CH_TYPE_MAX; j++) {
7400         if (m_channels[j] != NULL) {
7401             pChannel = m_channels[j];
7402             for (uint8_t i = 0; i < pChannel->getNumOfStreams(); i++) {
7403                 QCameraStream *pStream = pChannel->getStreamByIndex(i);
7404                 if (pStream != NULL) {
7405                     if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA))
7406                             || (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW))) {
7407                         continue;
7408                     }
7409                     pStream->getFrameDimension(str_dim);
7410                     if (str_dim.width > max_dim.width) {
7411                         max_dim.width = str_dim.width;
7412                     }
7413                     if (str_dim.height > max_dim.height) {
7414                         max_dim.height = str_dim.height;
7415                     }
7416                 }
7417             }
7418         }
7419     }
7420 
7421     for (uint8_t i = 0; i < curChannel->getNumOfStreams(); i++) {
7422         QCameraStream *pStream = curChannel->getStreamByIndex(i);
7423         if (pStream != NULL) {
7424             if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA))
7425                     || (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW))) {
7426                 continue;
7427             }
7428             pStream->getFrameDimension(str_dim);
7429             if (str_dim.width > max_dim.width) {
7430                 max_dim.width = str_dim.width;
7431             }
7432             if (str_dim.height > max_dim.height) {
7433                 max_dim.height = str_dim.height;
7434             }
7435         }
7436     }
7437     rc = mParameters.updateRAW(max_dim);
7438     return rc;
7439 }
7440 
7441 /*===========================================================================
7442  * FUNCTION   : getPaddingInfo
7443  *
7444  * DESCRIPTION: calculate padding per stream
7445  *
7446  * PARAMETERS :
7447  *   @streamType  : type of stream to be added
7448  *   @padding_info : Padding info. Output
7449  *
7450  * RETURN     : int32_t type of status
7451  *              NO_ERROR  -- success
7452  *              none-zero failure code
7453  *==========================================================================*/
getPaddingInfo(cam_stream_type_t streamType,cam_padding_info_t * padding_info)7454 int32_t QCamera2HardwareInterface::getPaddingInfo(cam_stream_type_t streamType,
7455         cam_padding_info_t *padding_info)
7456 {
7457     int32_t rc = NO_ERROR;
7458     if (streamType == CAM_STREAM_TYPE_ANALYSIS) {
7459         cam_analysis_info_t analysisInfo;
7460         cam_feature_mask_t featureMask;
7461 
7462         featureMask = 0;
7463         mParameters.getStreamPpMask(CAM_STREAM_TYPE_ANALYSIS, featureMask);
7464         rc = mParameters.getAnalysisInfo(
7465                 ((mParameters.getRecordingHintValue() == true) &&
7466                  mParameters.fdModeInVideo()),
7467                 featureMask,
7468                 &analysisInfo);
7469         if (rc != NO_ERROR) {
7470             LOGE("getAnalysisInfo failed, ret = %d", rc);
7471             return rc;
7472         }
7473 
7474         *padding_info = analysisInfo.analysis_padding_info;
7475     } else {
7476         *padding_info =
7477                 gCamCapability[mCameraId]->padding_info;
7478         if (streamType == CAM_STREAM_TYPE_PREVIEW || streamType == CAM_STREAM_TYPE_POSTVIEW) {
7479             padding_info->width_padding = mSurfaceStridePadding;
7480             padding_info->height_padding = CAM_PAD_TO_2;
7481         }
7482         if((!needReprocess())
7483                 || (streamType != CAM_STREAM_TYPE_SNAPSHOT)
7484                 || (!mParameters.isLLNoiseEnabled())) {
7485             padding_info->offset_info.offset_x = 0;
7486             padding_info->offset_info.offset_y = 0;
7487         }
7488     }
7489     return rc;
7490 }
7491 
7492 /*===========================================================================
7493  * FUNCTION   : addStreamToChannel
7494  *
7495  * DESCRIPTION: add a stream into a channel
7496  *
7497  * PARAMETERS :
7498  *   @pChannel   : ptr to channel obj
7499  *   @streamType : type of stream to be added
7500  *   @streamCB   : callback of stream
7501  *   @userData   : user data ptr to callback
7502  *
7503  * RETURN     : int32_t type of status
7504  *              NO_ERROR  -- success
7505  *              none-zero failure code
7506  *==========================================================================*/
addStreamToChannel(QCameraChannel * pChannel,cam_stream_type_t streamType,stream_cb_routine streamCB,void * userData)7507 int32_t QCamera2HardwareInterface::addStreamToChannel(QCameraChannel *pChannel,
7508                                                       cam_stream_type_t streamType,
7509                                                       stream_cb_routine streamCB,
7510                                                       void *userData)
7511 {
7512     int32_t rc = NO_ERROR;
7513     QCameraHeapMemory *pStreamInfo = NULL;
7514     uint32_t cam_type = MM_CAMERA_TYPE_MAIN;
7515     bool needAuxStream = FALSE;
7516 
7517     if (streamType == CAM_STREAM_TYPE_RAW) {
7518         prepareRawStream(pChannel);
7519     }
7520 
7521     if (isDualCamera()) {
7522         if (!((mParameters.isDCmAsymmetricSnapMode()) &&
7523                 (streamType == CAM_STREAM_TYPE_SNAPSHOT))) {
7524             cam_type |= MM_CAMERA_TYPE_AUX;
7525         } else {
7526             needAuxStream = TRUE;
7527         }
7528     }
7529 
7530     pStreamInfo = allocateStreamInfoBuf(streamType,
7531             getStreamRefCount(streamType, cam_type), cam_type);
7532     if (pStreamInfo == NULL) {
7533         LOGE("no mem for stream info buf");
7534         return NO_MEMORY;
7535     }
7536 
7537     bool bDynAllocBuf = false;
7538     if (isZSLMode() && streamType == CAM_STREAM_TYPE_SNAPSHOT) {
7539         bDynAllocBuf = true;
7540     }
7541 
7542     cam_padding_info_t padding_info;
7543     getPaddingInfo(streamType, &padding_info);
7544 
7545     bool deferAllocation = needDeferred(streamType);
7546     LOGD("deferAllocation = %d bDynAllocBuf = %d, stream type = %d",
7547             deferAllocation, bDynAllocBuf, streamType);
7548     rc = pChannel->addStream(*this,
7549             pStreamInfo, NULL, &padding_info,
7550             streamCB, userData, bDynAllocBuf,
7551             deferAllocation, ROTATE_0, cam_type);
7552 
7553     if (rc != NO_ERROR) {
7554         LOGE("add stream type (%d) cam = %d failed, ret = %d",
7555                streamType, cam_type, rc);
7556         return rc;
7557     }
7558 
7559     /*Add stream for Asymmetric dual camera use case*/
7560     if (needAuxStream) {
7561         cam_type = MM_CAMERA_TYPE_AUX;
7562         pStreamInfo = allocateStreamInfoBuf(streamType,
7563                 getStreamRefCount(streamType, cam_type), cam_type);
7564         if (pStreamInfo == NULL) {
7565             LOGE("no mem for stream info buf");
7566             return NO_MEMORY;
7567         }
7568         rc = pChannel->addStream(*this,
7569                 pStreamInfo, NULL, &padding_info,
7570                 streamCB, userData, bDynAllocBuf,
7571                 deferAllocation, ROTATE_0, cam_type);
7572         if (rc != NO_ERROR) {
7573             LOGE("add stream type (%d) cam = %d failed, ret = %d",
7574                    streamType, cam_type, rc);
7575             return rc;
7576         }
7577     }
7578     return rc;
7579 }
7580 
7581 /*===========================================================================
7582  * FUNCTION   : addPreviewChannel
7583  *
7584  * DESCRIPTION: add a preview channel that contains a preview stream
7585  *
7586  * PARAMETERS : none
7587  *
7588  * RETURN     : int32_t type of status
7589  *              NO_ERROR  -- success
7590  *              none-zero failure code
7591  *==========================================================================*/
addPreviewChannel()7592 int32_t QCamera2HardwareInterface::addPreviewChannel()
7593 {
7594     int32_t rc = NO_ERROR;
7595     QCameraChannel *pChannel = NULL;
7596     char value[PROPERTY_VALUE_MAX];
7597     bool raw_yuv = false;
7598 
7599 
7600     if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
7601         // if we had preview channel before, delete it first
7602         delete m_channels[QCAMERA_CH_TYPE_PREVIEW];
7603         m_channels[QCAMERA_CH_TYPE_PREVIEW] = NULL;
7604     }
7605 
7606     uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_PREVIEW);
7607     pChannel = new QCameraChannel(handle, mCameraHandle->ops);
7608     if (NULL == pChannel) {
7609         LOGE("no mem for preview channel");
7610         return NO_MEMORY;
7611     }
7612 
7613     // preview only channel, don't need bundle attr and cb
7614     rc = pChannel->init(NULL, NULL, NULL);
7615     if (rc != NO_ERROR) {
7616         LOGE("init preview channel failed, ret = %d", rc);
7617         delete pChannel;
7618         return rc;
7619     }
7620 
7621     // meta data stream always coexists with preview if applicable
7622     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
7623             metadata_stream_cb_routine, this);
7624     if (rc != NO_ERROR) {
7625         LOGE("add metadata stream failed, ret = %d", rc);
7626         delete pChannel;
7627         return rc;
7628     }
7629 
7630     if (isRdiMode()) {
7631         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
7632                 rdi_mode_stream_cb_routine, this);
7633     } else {
7634         if (isNoDisplayMode()) {
7635             rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
7636                     nodisplay_preview_stream_cb_routine, this);
7637         } else {
7638             rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
7639                     preview_stream_cb_routine, this);
7640             if (needSyncCB(CAM_STREAM_TYPE_PREVIEW) == TRUE) {
7641                 pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
7642                         synchronous_stream_cb_routine);
7643             }
7644         }
7645     }
7646 
7647     if (rc != NO_ERROR) {
7648         LOGE("add raw/preview stream failed, ret = %d", rc);
7649         delete pChannel;
7650         return rc;
7651     }
7652 
7653     if (((mParameters.fdModeInVideo())
7654             || (mParameters.getDcrf() == true)
7655             || (mParameters.getRecordingHintValue() != true))
7656             && (!isSecureMode())) {
7657         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
7658                 NULL, this);
7659         if (rc != NO_ERROR) {
7660             LOGE("add Analysis stream failed, ret = %d", rc);
7661             delete pChannel;
7662             return rc;
7663         }
7664     }
7665 
7666     property_get("persist.camera.raw_yuv", value, "0");
7667     raw_yuv = atoi(value) > 0 ? true : false;
7668     if ( raw_yuv ) {
7669         rc = addStreamToChannel(pChannel,CAM_STREAM_TYPE_RAW,
7670                 preview_raw_stream_cb_routine,this);
7671         if ( rc != NO_ERROR ) {
7672             LOGE("add raw stream failed, ret = %d", __FUNCTION__, rc);
7673             delete pChannel;
7674             return rc;
7675         }
7676     }
7677 
7678     if (rc != NO_ERROR) {
7679         LOGE("add preview stream failed, ret = %d", rc);
7680         delete pChannel;
7681         return rc;
7682     }
7683 
7684     m_channels[QCAMERA_CH_TYPE_PREVIEW] = pChannel;
7685     return rc;
7686 }
7687 
7688 /*===========================================================================
7689  * FUNCTION   : addVideoChannel
7690  *
7691  * DESCRIPTION: add a video channel that contains a video stream
7692  *
7693  * PARAMETERS : none
7694  *
7695  * RETURN     : int32_t type of status
7696  *              NO_ERROR  -- success
7697  *              none-zero failure code
7698  *==========================================================================*/
addVideoChannel()7699 int32_t QCamera2HardwareInterface::addVideoChannel()
7700 {
7701     int32_t rc = NO_ERROR;
7702     QCameraVideoChannel *pChannel = NULL;
7703 
7704     if (m_channels[QCAMERA_CH_TYPE_VIDEO] != NULL) {
7705         // if we had video channel before, delete it first
7706         delete m_channels[QCAMERA_CH_TYPE_VIDEO];
7707         m_channels[QCAMERA_CH_TYPE_VIDEO] = NULL;
7708     }
7709 
7710     uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_VIDEO);
7711     pChannel = new QCameraVideoChannel(handle, mCameraHandle->ops);
7712     if (NULL == pChannel) {
7713         LOGE("no mem for video channel");
7714         return NO_MEMORY;
7715     }
7716 
7717     if (isLowPowerMode()) {
7718         mm_camera_channel_attr_t attr;
7719         memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
7720         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
7721         attr.look_back = 0; //wait for future frame for liveshot
7722         attr.post_frame_skip = mParameters.getZSLBurstInterval();
7723         attr.water_mark = 1; //hold min buffers possible in Q
7724         attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
7725         rc = pChannel->init(&attr, snapshot_channel_cb_routine, this);
7726     } else {
7727         // preview only channel, don't need bundle attr and cb
7728         rc = pChannel->init(NULL, NULL, NULL);
7729     }
7730 
7731     if (rc != 0) {
7732         LOGE("init video channel failed, ret = %d", rc);
7733         delete pChannel;
7734         return rc;
7735     }
7736 
7737     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_VIDEO,
7738             video_stream_cb_routine, this);
7739 
7740     if (rc != NO_ERROR) {
7741         LOGE("add video stream failed, ret = %d", rc);
7742         delete pChannel;
7743         return rc;
7744     }
7745 
7746     m_channels[QCAMERA_CH_TYPE_VIDEO] = pChannel;
7747     return rc;
7748 }
7749 
7750 /*===========================================================================
7751  * FUNCTION   : addSnapshotChannel
7752  *
7753  * DESCRIPTION: add a snapshot channel that contains a snapshot stream
7754  *
7755  * PARAMETERS : none
7756  *
7757  * RETURN     : int32_t type of status
7758  *              NO_ERROR  -- success
7759  *              none-zero failure code
7760  * NOTE       : Add this channel for live snapshot usecase. Regular capture will
7761  *              use addCaptureChannel.
7762  *==========================================================================*/
addSnapshotChannel()7763 int32_t QCamera2HardwareInterface::addSnapshotChannel()
7764 {
7765     int32_t rc = NO_ERROR;
7766     QCameraChannel *pChannel = NULL;
7767 
7768     if (m_channels[QCAMERA_CH_TYPE_SNAPSHOT] != NULL) {
7769         // if we had ZSL channel before, delete it first
7770         delete m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
7771         m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = NULL;
7772     }
7773 
7774     uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_SNAPSHOT);
7775     pChannel = new QCameraChannel(handle, mCameraHandle->ops);
7776     if (NULL == pChannel) {
7777         LOGE("no mem for snapshot channel");
7778         return NO_MEMORY;
7779     }
7780 
7781     mm_camera_channel_attr_t attr;
7782     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
7783     attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
7784     attr.look_back = 0; //wait for future frame for liveshot
7785     attr.post_frame_skip = mParameters.getZSLBurstInterval();
7786     attr.water_mark = 1; //hold min buffers possible in Q
7787     attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
7788     attr.priority = MM_CAMERA_SUPER_BUF_PRIORITY_LOW;
7789     rc = pChannel->init(&attr, snapshot_channel_cb_routine, this);
7790     if (rc != NO_ERROR) {
7791         LOGE("init snapshot channel failed, ret = %d", rc);
7792         delete pChannel;
7793         return rc;
7794     }
7795 
7796     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
7797             NULL, NULL);
7798     if (rc != NO_ERROR) {
7799         LOGE("add snapshot stream failed, ret = %d", rc);
7800         delete pChannel;
7801         return rc;
7802     }
7803 
7804     m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = pChannel;
7805     return rc;
7806 }
7807 
7808 /*===========================================================================
7809  * FUNCTION   : addRawChannel
7810  *
7811  * DESCRIPTION: add a raw channel that contains a raw image stream
7812  *
7813  * PARAMETERS : none
7814  *
7815  * RETURN     : int32_t type of status
7816  *              NO_ERROR  -- success
7817  *              none-zero failure code
7818  *==========================================================================*/
addRawChannel()7819 int32_t QCamera2HardwareInterface::addRawChannel()
7820 {
7821     int32_t rc = NO_ERROR;
7822     QCameraChannel *pChannel = NULL;
7823 
7824     if (m_channels[QCAMERA_CH_TYPE_RAW] != NULL) {
7825         // if we had raw channel before, delete it first
7826         delete m_channels[QCAMERA_CH_TYPE_RAW];
7827         m_channels[QCAMERA_CH_TYPE_RAW] = NULL;
7828     }
7829 
7830     uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_RAW);
7831     pChannel = new QCameraChannel(handle, mCameraHandle->ops);
7832     if (NULL == pChannel) {
7833         LOGE("no mem for raw channel");
7834         return NO_MEMORY;
7835     }
7836 
7837     if (mParameters.getofflineRAW()) {
7838         mm_camera_channel_attr_t attr;
7839         memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
7840         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
7841         attr.look_back = mParameters.getZSLBackLookCount();
7842         attr.post_frame_skip = mParameters.getZSLBurstInterval();
7843         attr.water_mark = 1;
7844         attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
7845         rc = pChannel->init(&attr, raw_channel_cb_routine, this);
7846         if (rc != NO_ERROR) {
7847             LOGE("init RAW channel failed, ret = %d", rc);
7848             delete pChannel;
7849             return rc;
7850         }
7851     } else {
7852         rc = pChannel->init(NULL, NULL, NULL);
7853         if (rc != NO_ERROR) {
7854             LOGE("init raw channel failed, ret = %d", rc);
7855             delete pChannel;
7856             return rc;
7857         }
7858     }
7859 
7860     if (!mParameters.isZSLMode()) {
7861         // meta data stream always coexists with snapshot in regular RAW capture case
7862         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
7863                 metadata_stream_cb_routine, this);
7864         if (rc != NO_ERROR) {
7865             LOGE("add metadata stream failed, ret = %d", rc);
7866             delete pChannel;
7867             return rc;
7868         }
7869     }
7870 
7871     if (mParameters.getofflineRAW()) {
7872         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
7873                 NULL, this);
7874     } else if(isSecureMode()) {
7875         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
7876                 secure_stream_cb_routine, this);
7877     } else {
7878         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
7879                 raw_stream_cb_routine, this);
7880     }
7881     if (rc != NO_ERROR) {
7882         LOGE("add snapshot stream failed, ret = %d", rc);
7883         delete pChannel;
7884         return rc;
7885     }
7886     m_channels[QCAMERA_CH_TYPE_RAW] = pChannel;
7887     return rc;
7888 }
7889 
7890 /*===========================================================================
7891  * FUNCTION   : addZSLChannel
7892  *
7893  * DESCRIPTION: add a ZSL channel that contains a preview stream and
7894  *              a snapshot stream
7895  *
7896  * PARAMETERS : none
7897  *
7898  * RETURN     : int32_t type of status
7899  *              NO_ERROR  -- success
7900  *              none-zero failure code
7901  *==========================================================================*/
addZSLChannel()7902 int32_t QCamera2HardwareInterface::addZSLChannel()
7903 {
7904     int32_t rc = NO_ERROR;
7905     QCameraPicChannel *pChannel = NULL;
7906     char value[PROPERTY_VALUE_MAX];
7907     bool raw_yuv = false;
7908 
7909     if (m_channels[QCAMERA_CH_TYPE_ZSL] != NULL) {
7910         // if we had ZSL channel before, delete it first
7911         delete m_channels[QCAMERA_CH_TYPE_ZSL];
7912         m_channels[QCAMERA_CH_TYPE_ZSL] = NULL;
7913     }
7914 
7915     uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_ZSL);
7916     pChannel = new QCameraPicChannel(handle,
7917                                      mCameraHandle->ops);
7918     if (NULL == pChannel) {
7919         LOGE("no mem for ZSL channel");
7920         return NO_MEMORY;
7921     }
7922 
7923     // ZSL channel, init with bundle attr and cb
7924     mm_camera_channel_attr_t attr;
7925     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
7926     if (mParameters.isSceneSelectionEnabled()) {
7927         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
7928     } else {
7929         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
7930     }
7931     attr.look_back = mParameters.getZSLBackLookCount();
7932     attr.post_frame_skip = mParameters.getZSLBurstInterval();
7933     if (mParameters.isOEMFeatEnabled()) {
7934         LOGD("EDGE SMOOTH frameskip enabled");
7935         attr.post_frame_skip += mParameters.isOEMFeatFrameSkipEnabled();
7936     }
7937     attr.water_mark = mParameters.getZSLQueueDepth();
7938     attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
7939     attr.user_expected_frame_id =
7940         mParameters.isInstantCaptureEnabled() ? (uint8_t)mParameters.getAecFrameBoundValue() : 0;
7941 
7942     //Enabled matched queue
7943     if (isFrameSyncEnabled()) {
7944         LOGH("Enabling frame sync for dual camera, camera Id: %d",
7945                  mCameraId);
7946         attr.enable_frame_sync = 1;
7947     }
7948     rc = pChannel->init(&attr,
7949                         zsl_channel_cb,
7950                         this);
7951     if (rc != 0) {
7952         LOGE("init ZSL channel failed, ret = %d", rc);
7953         delete pChannel;
7954         return rc;
7955     }
7956 
7957     // meta data stream always coexists with preview if applicable
7958     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
7959             metadata_stream_cb_routine, this);
7960     if (rc != NO_ERROR) {
7961         LOGE("add metadata stream failed, ret = %d", rc);
7962         delete pChannel;
7963         return rc;
7964     }
7965 
7966     if (isNoDisplayMode()) {
7967         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
7968                 nodisplay_preview_stream_cb_routine, this);
7969     } else {
7970         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
7971                 preview_stream_cb_routine, this);
7972         if (needSyncCB(CAM_STREAM_TYPE_PREVIEW) == TRUE) {
7973             pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
7974                     synchronous_stream_cb_routine);
7975         }
7976     }
7977     if (rc != NO_ERROR) {
7978         LOGE("add preview stream failed, ret = %d", rc);
7979         delete pChannel;
7980         return rc;
7981     }
7982 
7983     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
7984             NULL, this);
7985     if (rc != NO_ERROR) {
7986         LOGE("add snapshot stream failed, ret = %d", rc);
7987         delete pChannel;
7988         return rc;
7989     }
7990 
7991     if (!isSecureMode()) {
7992         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
7993                 NULL, this);
7994         if (rc != NO_ERROR) {
7995             LOGE("add Analysis stream failed, ret = %d", rc);
7996             delete pChannel;
7997             return rc;
7998         }
7999     }
8000 
8001     property_get("persist.camera.raw_yuv", value, "0");
8002     raw_yuv = atoi(value) > 0 ? true : false;
8003     if (raw_yuv) {
8004         rc = addStreamToChannel(pChannel,
8005                                 CAM_STREAM_TYPE_RAW,
8006                                 preview_raw_stream_cb_routine,
8007                                 this);
8008         if (rc != NO_ERROR) {
8009             LOGE("add raw stream failed, ret = %d", rc);
8010             delete pChannel;
8011             return rc;
8012         }
8013     }
8014 
8015     m_channels[QCAMERA_CH_TYPE_ZSL] = pChannel;
8016     return rc;
8017 }
8018 
8019 /*===========================================================================
8020  * FUNCTION   : addCaptureChannel
8021  *
8022  * DESCRIPTION: add a capture channel that contains a snapshot stream
8023  *              and a postview stream
8024  *
8025  * PARAMETERS : none
8026  *
8027  * RETURN     : int32_t type of status
8028  *              NO_ERROR  -- success
8029  *              none-zero failure code
8030  * NOTE       : Add this channel for regular capture usecase.
8031  *              For Live snapshot usecase, use addSnapshotChannel.
8032  *==========================================================================*/
addCaptureChannel()8033 int32_t QCamera2HardwareInterface::addCaptureChannel()
8034 {
8035     int32_t rc = NO_ERROR;
8036     QCameraPicChannel *pChannel = NULL;
8037     char value[PROPERTY_VALUE_MAX];
8038     bool raw_yuv = false;
8039 
8040     if (m_channels[QCAMERA_CH_TYPE_CAPTURE] != NULL) {
8041         delete m_channels[QCAMERA_CH_TYPE_CAPTURE];
8042         m_channels[QCAMERA_CH_TYPE_CAPTURE] = NULL;
8043     }
8044 
8045     uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_CAPTURE);
8046     pChannel = new QCameraPicChannel(handle, mCameraHandle->ops);
8047     if (NULL == pChannel) {
8048         LOGE("no mem for capture channel");
8049         return NO_MEMORY;
8050     }
8051 
8052     // Capture channel, only need snapshot and postview streams start together
8053     mm_camera_channel_attr_t attr;
8054     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
8055     if ( mLongshotEnabled ) {
8056         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
8057         attr.look_back = mParameters.getZSLBackLookCount();
8058         attr.water_mark = mParameters.getZSLQueueDepth();
8059     } else {
8060         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
8061     }
8062     attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
8063 
8064     rc = pChannel->init(&attr,
8065                         capture_channel_cb_routine,
8066                         this);
8067     if (rc != NO_ERROR) {
8068         LOGE("init capture channel failed, ret = %d", rc);
8069         delete pChannel;
8070         return rc;
8071     }
8072 
8073     // meta data stream always coexists with snapshot in regular capture case
8074     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
8075             metadata_stream_cb_routine, this);
8076     if (rc != NO_ERROR) {
8077         LOGE("add metadata stream failed, ret = %d", rc);
8078         delete pChannel;
8079         return rc;
8080     }
8081 
8082     if (mLongshotEnabled) {
8083         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
8084                 preview_stream_cb_routine, this);
8085         if (rc != NO_ERROR) {
8086             LOGE("add preview stream failed, ret = %d", rc);
8087             delete pChannel;
8088             return rc;
8089         }
8090         if (needSyncCB(CAM_STREAM_TYPE_PREVIEW) == TRUE) {
8091             pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
8092                     synchronous_stream_cb_routine);
8093         }
8094     //Not adding the postview stream to the capture channel if Quadra CFA is enabled.
8095     } else if (!mParameters.getQuadraCfa()) {
8096         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_POSTVIEW,
8097                                 NULL, this);
8098         if (rc != NO_ERROR) {
8099             LOGE("add postview stream failed, ret = %d", rc);
8100             delete pChannel;
8101             return rc;
8102         }
8103     }
8104 
8105     if (!mParameters.getofflineRAW()) {
8106         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
8107                 NULL, this);
8108         if (rc != NO_ERROR) {
8109             LOGE("add snapshot stream failed, ret = %d", rc);
8110             delete pChannel;
8111             return rc;
8112         }
8113     }
8114 
8115     stream_cb_routine stream_cb = NULL;
8116     property_get("persist.camera.raw_yuv", value, "0");
8117     raw_yuv = atoi(value) > 0 ? true : false;
8118 
8119     if (raw_yuv) {
8120         stream_cb = snapshot_raw_stream_cb_routine;
8121     }
8122 
8123     if ((raw_yuv) || (mParameters.getofflineRAW())) {
8124         rc = addStreamToChannel(pChannel,
8125                 CAM_STREAM_TYPE_RAW, stream_cb, this);
8126         if (rc != NO_ERROR) {
8127             LOGE("add raw stream failed, ret = %d", rc);
8128             delete pChannel;
8129             return rc;
8130         }
8131     }
8132 
8133     m_channels[QCAMERA_CH_TYPE_CAPTURE] = pChannel;
8134     return rc;
8135 }
8136 
8137 /*===========================================================================
8138  * FUNCTION   : addMetaDataChannel
8139  *
8140  * DESCRIPTION: add a meta data channel that contains a metadata stream
8141  *
8142  * PARAMETERS : none
8143  *
8144  * RETURN     : int32_t type of status
8145  *              NO_ERROR  -- success
8146  *              none-zero failure code
8147  *==========================================================================*/
addMetaDataChannel()8148 int32_t QCamera2HardwareInterface::addMetaDataChannel()
8149 {
8150     int32_t rc = NO_ERROR;
8151     QCameraChannel *pChannel = NULL;
8152 
8153     if (m_channels[QCAMERA_CH_TYPE_METADATA] != NULL) {
8154         delete m_channels[QCAMERA_CH_TYPE_METADATA];
8155         m_channels[QCAMERA_CH_TYPE_METADATA] = NULL;
8156     }
8157 
8158     uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_METADATA);
8159     pChannel = new QCameraChannel(handle, mCameraHandle->ops);
8160     if (NULL == pChannel) {
8161         LOGE("no mem for metadata channel");
8162         return NO_MEMORY;
8163     }
8164 
8165     rc = pChannel->init(NULL,
8166                         NULL,
8167                         NULL);
8168     if (rc != NO_ERROR) {
8169         LOGE("init metadata channel failed, ret = %d", rc);
8170         delete pChannel;
8171         return rc;
8172     }
8173 
8174     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
8175             metadata_stream_cb_routine, this);
8176     if (rc != NO_ERROR) {
8177         LOGE("add metadata stream failed, ret = %d", rc);
8178         delete pChannel;
8179         return rc;
8180     }
8181 
8182     m_channels[QCAMERA_CH_TYPE_METADATA] = pChannel;
8183     return rc;
8184 }
8185 
8186 /*===========================================================================
8187  * FUNCTION   : addCallbackChannel
8188  *
8189  * DESCRIPTION: add a callback channel that contains a callback stream
8190  *
8191  * PARAMETERS : none
8192  *
8193  * RETURN     : int32_t type of status
8194  *              NO_ERROR  -- success
8195  *              none-zero failure code
8196  *==========================================================================*/
addCallbackChannel()8197 int32_t QCamera2HardwareInterface::addCallbackChannel()
8198 {
8199     int32_t rc = NO_ERROR;
8200     QCameraChannel *pChannel = NULL;
8201 
8202     if (m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL) {
8203         delete m_channels[QCAMERA_CH_TYPE_CALLBACK];
8204         m_channels[QCAMERA_CH_TYPE_CALLBACK] = NULL;
8205     }
8206 
8207     uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_CALLBACK);
8208     pChannel = new QCameraChannel(handle, mCameraHandle->ops);
8209     if (NULL == pChannel) {
8210         LOGE("no mem for callback channel");
8211         return NO_MEMORY;
8212     }
8213 
8214     rc = pChannel->init(NULL, NULL, this);
8215     if (rc != NO_ERROR) {
8216         LOGE("init callback channel failed, ret = %d",
8217                  rc);
8218         delete pChannel;
8219         return rc;
8220     }
8221 
8222     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_CALLBACK,
8223             callback_stream_cb_routine, this);
8224     if (rc != NO_ERROR) {
8225         LOGE("add callback stream failed, ret = %d", rc);
8226         delete pChannel;
8227         return rc;
8228     }
8229 
8230     m_channels[QCAMERA_CH_TYPE_CALLBACK] = pChannel;
8231     return rc;
8232 }
8233 
8234 
8235 /*===========================================================================
8236  * FUNCTION   : addAnalysisChannel
8237  *
8238  * DESCRIPTION: add a analysis channel that contains a analysis stream
8239  *
8240  * PARAMETERS : none
8241  *
8242  * RETURN     : int32_t type of status
8243  *              NO_ERROR  -- success
8244  *              none-zero failure code
8245  *==========================================================================*/
addAnalysisChannel()8246 int32_t QCamera2HardwareInterface::addAnalysisChannel()
8247 {
8248     int32_t rc = NO_ERROR;
8249     QCameraChannel *pChannel = NULL;
8250 
8251     if (m_channels[QCAMERA_CH_TYPE_ANALYSIS] != NULL) {
8252         delete m_channels[QCAMERA_CH_TYPE_ANALYSIS];
8253         m_channels[QCAMERA_CH_TYPE_ANALYSIS] = NULL;
8254     }
8255 
8256     uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_ANALYSIS);
8257     pChannel = new QCameraChannel(handle, mCameraHandle->ops);
8258     if (NULL == pChannel) {
8259         LOGE("no mem for metadata channel");
8260         return NO_MEMORY;
8261     }
8262 
8263     rc = pChannel->init(NULL, NULL, this);
8264     if (rc != NO_ERROR) {
8265         LOGE("init Analysis channel failed, ret = %d", rc);
8266         delete pChannel;
8267         return rc;
8268     }
8269 
8270     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
8271             NULL, this);
8272     if (rc != NO_ERROR) {
8273         LOGE("add Analysis stream failed, ret = %d", rc);
8274         delete pChannel;
8275         return rc;
8276     }
8277 
8278     m_channels[QCAMERA_CH_TYPE_ANALYSIS] = pChannel;
8279     return rc;
8280 }
8281 
8282 
8283 /*===========================================================================
8284  * FUNCTION   : getPPConfig
8285  *
8286  * DESCRIPTION: get Post processing configaration data
8287  *
8288  * PARAMETERS :
8289  * @pp config:  pp config structure pointer,
8290  * @curIndex:  current pp channel index
8291  * @multipass: Flag if multipass prcessing enabled.
8292  *
8293  * RETURN     : int32_t type of status
8294  *              NO_ERROR  -- success
8295  *              none-zero failure code
8296  *==========================================================================*/
getPPConfig(cam_pp_feature_config_t & pp_config,int8_t curIndex,bool multipass)8297 int32_t QCamera2HardwareInterface::getPPConfig(cam_pp_feature_config_t &pp_config,
8298         int8_t curIndex, bool multipass)
8299 {
8300     int32_t rc = NO_ERROR;
8301     int32_t feature_set = 0;
8302 
8303     if (multipass) {
8304         LOGW("Multi pass enabled. Total Pass = %d, cur index = %d",
8305                 mParameters.getReprocCount(), curIndex);
8306     }
8307 
8308     LOGH("Supported pproc feature mask = %llx",
8309             gCamCapability[mCameraId]->qcom_supported_feature_mask);
8310     cam_feature_mask_t feature_mask = gCamCapability[mCameraId]->qcom_supported_feature_mask;
8311     int32_t zoomLevel = mParameters.getParmZoomLevel();
8312     uint32_t rotation = mParameters.getJpegRotation();
8313     int32_t effect = mParameters.getEffectValue();
8314 
8315     pp_config.cur_reproc_count = curIndex + 1;
8316     pp_config.total_reproc_count = mParameters.getReprocCount();
8317 
8318     //Checking what feature mask to enable
8319     if (curIndex == 0) {
8320         if (mParameters.getQuadraCfa()) {
8321             feature_set = 2;
8322         } else {
8323             feature_set = 0;
8324         }
8325     } else if (curIndex == 1) {
8326         if (mParameters.getQuadraCfa()) {
8327             feature_set = 0;
8328         } else {
8329             feature_set = 1;
8330         }
8331     }
8332 
8333     switch(feature_set) {
8334         case 0:
8335             //Configure feature mask for first pass of reprocessing
8336             //check if any effects are enabled
8337             if ((CAM_EFFECT_MODE_OFF != effect) &&
8338                 (feature_mask & CAM_QCOM_FEATURE_EFFECT)) {
8339                 pp_config.feature_mask |= CAM_QCOM_FEATURE_EFFECT;
8340                 pp_config.effect = effect;
8341             }
8342 
8343             //check for features that need to be enabled by default like sharpness
8344             //(if supported by hw).
8345             if ((feature_mask & CAM_QCOM_FEATURE_SHARPNESS) &&
8346                 !mParameters.isOptiZoomEnabled()) {
8347                 pp_config.feature_mask |= CAM_QCOM_FEATURE_SHARPNESS;
8348                 pp_config.sharpness = mParameters.getSharpness();
8349             }
8350 
8351             //check if zoom is enabled
8352             if ((zoomLevel > 0) && (feature_mask & CAM_QCOM_FEATURE_CROP)) {
8353                 pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
8354             }
8355 
8356             if (mParameters.isWNREnabled() &&
8357                 (feature_mask & CAM_QCOM_FEATURE_DENOISE2D)) {
8358                 pp_config.feature_mask |= CAM_QCOM_FEATURE_DENOISE2D;
8359                 pp_config.denoise2d.denoise_enable = 1;
8360                 pp_config.denoise2d.process_plates =
8361                         mParameters.getDenoiseProcessPlate(CAM_INTF_PARM_WAVELET_DENOISE);
8362             }
8363 
8364             if (isCACEnabled()) {
8365                 pp_config.feature_mask |= CAM_QCOM_FEATURE_CAC;
8366             }
8367 
8368             //check if rotation is required
8369             if ((feature_mask & CAM_QCOM_FEATURE_ROTATION) && (rotation > 0)) {
8370                 pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION;
8371                 if (rotation == 0) {
8372                     pp_config.rotation = ROTATE_0;
8373                 } else if (rotation == 90) {
8374                     pp_config.rotation = ROTATE_90;
8375                 } else if (rotation == 180) {
8376                     pp_config.rotation = ROTATE_180;
8377                 } else if (rotation == 270) {
8378                     pp_config.rotation = ROTATE_270;
8379                 }
8380             }
8381 
8382             if (mParameters.isHDREnabled()){
8383                 pp_config.feature_mask |= CAM_QCOM_FEATURE_HDR;
8384                 pp_config.hdr_param.hdr_enable = 1;
8385                 pp_config.hdr_param.hdr_need_1x = mParameters.isHDR1xFrameEnabled();
8386                 pp_config.hdr_param.hdr_mode = CAM_HDR_MODE_MULTIFRAME;
8387             } else {
8388                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_HDR;
8389                 pp_config.hdr_param.hdr_enable = 0;
8390             }
8391 
8392             //check if scaling is enabled
8393             if ((feature_mask & CAM_QCOM_FEATURE_SCALE) &&
8394                 mParameters.isReprocScaleEnabled() &&
8395                 mParameters.isUnderReprocScaling()){
8396                 pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
8397                 mParameters.getPicSizeFromAPK(
8398                         pp_config.scale_param.output_width,
8399                         pp_config.scale_param.output_height);
8400             }
8401 
8402             if(mParameters.isUbiFocusEnabled()) {
8403                 pp_config.feature_mask |= CAM_QCOM_FEATURE_UBIFOCUS;
8404             } else {
8405                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_UBIFOCUS;
8406             }
8407 
8408             if(mParameters.isUbiRefocus()) {
8409                 pp_config.feature_mask |= CAM_QCOM_FEATURE_REFOCUS;
8410                 pp_config.misc_buf_param.misc_buffer_index = 0;
8411             } else {
8412                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_REFOCUS;
8413             }
8414 
8415             if(mParameters.isChromaFlashEnabled()) {
8416                 pp_config.feature_mask |= CAM_QCOM_FEATURE_CHROMA_FLASH;
8417                 pp_config.flash_value = CAM_FLASH_ON;
8418             } else {
8419                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_CHROMA_FLASH;
8420             }
8421 
8422             if(mParameters.isOptiZoomEnabled() && (0 <= zoomLevel)) {
8423                 pp_config.feature_mask |= CAM_QCOM_FEATURE_OPTIZOOM;
8424                 pp_config.zoom_level = (uint8_t) zoomLevel;
8425             } else {
8426                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_OPTIZOOM;
8427             }
8428 
8429             if (mParameters.getofflineRAW()) {
8430                 pp_config.feature_mask |= CAM_QCOM_FEATURE_RAW_PROCESSING;
8431             }
8432 
8433             if (mParameters.isTruePortraitEnabled()) {
8434                 pp_config.feature_mask |= CAM_QCOM_FEATURE_TRUEPORTRAIT;
8435                 pp_config.misc_buf_param.misc_buffer_index = 0;
8436             } else {
8437                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_TRUEPORTRAIT;
8438             }
8439 
8440             if(mParameters.isStillMoreEnabled()) {
8441                 pp_config.feature_mask |= CAM_QCOM_FEATURE_STILLMORE;
8442             } else {
8443                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_STILLMORE;
8444             }
8445 
8446             if (mParameters.isOEMFeatEnabled()) {
8447                 pp_config.feature_mask |= CAM_OEM_FEATURE_1;
8448             }
8449 
8450             if (mParameters.getCDSMode() != CAM_CDS_MODE_OFF) {
8451                 if (feature_mask & CAM_QCOM_FEATURE_DSDN) {
8452                     pp_config.feature_mask |= CAM_QCOM_FEATURE_DSDN;
8453                 } else {
8454                     pp_config.feature_mask |= CAM_QCOM_FEATURE_CDS;
8455                 }
8456             }
8457 
8458             if ((multipass) &&
8459                     (m_postprocessor.getPPChannelCount() > 1)
8460                     && (!mParameters.getQuadraCfa())) {
8461                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_PP_PASS_2;
8462                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_ROTATION;
8463                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_CDS;
8464                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_DSDN;
8465                 pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
8466             } else {
8467                 pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
8468             }
8469 
8470             cam_dimension_t thumb_src_dim;
8471             cam_dimension_t thumb_dst_dim;
8472             mParameters.getThumbnailSize(&(thumb_dst_dim.width), &(thumb_dst_dim.height));
8473             mParameters.getStreamDimension(CAM_STREAM_TYPE_POSTVIEW,thumb_src_dim);
8474             if ((thumb_dst_dim.width != thumb_src_dim.width) ||
8475                     (thumb_dst_dim.height != thumb_src_dim.height)) {
8476                 if (thumb_dst_dim.width != 0 && thumb_dst_dim.height != 0) {
8477                     pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
8478                 }
8479             }
8480 
8481             break;
8482 
8483         case 1:
8484             //Configure feature mask for second pass of reprocessing
8485             pp_config.feature_mask |= CAM_QCOM_FEATURE_PP_PASS_2;
8486             if ((feature_mask & CAM_QCOM_FEATURE_ROTATION) && (rotation > 0)) {
8487                 pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION;
8488                 if (rotation == 0) {
8489                     pp_config.rotation = ROTATE_0;
8490                 } else if (rotation == 90) {
8491                     pp_config.rotation = ROTATE_90;
8492                 } else if (rotation == 180) {
8493                     pp_config.rotation = ROTATE_180;
8494                 } else if (rotation == 270) {
8495                     pp_config.rotation = ROTATE_270;
8496                 }
8497             }
8498             if (mParameters.getCDSMode() != CAM_CDS_MODE_OFF) {
8499                 if (feature_mask & CAM_QCOM_FEATURE_DSDN) {
8500                     pp_config.feature_mask |= CAM_QCOM_FEATURE_DSDN;
8501                 } else {
8502                     pp_config.feature_mask |= CAM_QCOM_FEATURE_CDS;
8503                 }
8504             }
8505             pp_config.feature_mask &= ~CAM_QCOM_FEATURE_RAW_PROCESSING;
8506             pp_config.feature_mask &= ~CAM_QCOM_FEATURE_METADATA_PROCESSING;
8507             pp_config.feature_mask &= ~CAM_QCOM_FEATURE_METADATA_BYPASS;
8508             break;
8509 
8510         case 2:
8511             //Setting feature for Quadra CFA
8512             pp_config.feature_mask |= CAM_QCOM_FEATURE_QUADRA_CFA;
8513             break;
8514 
8515     }
8516 
8517     LOGH("pproc feature mask set = %llx pass count = %d",
8518         pp_config.feature_mask, curIndex);
8519     return rc;
8520 }
8521 
8522 /*===========================================================================
8523  * FUNCTION   : addReprocChannel
8524  *
8525  * DESCRIPTION: add a reprocess channel that will do reprocess on frames
8526  *              coming from input channel
8527  *
8528  * PARAMETERS :
8529  *   @pInputChannel : ptr to input channel whose frames will be post-processed
8530  *   @cur_channel_index : Current channel index in multipass
8531  *
8532  * RETURN     : Ptr to the newly created channel obj. NULL if failed.
8533  *==========================================================================*/
addReprocChannel(QCameraChannel * pInputChannel,int8_t cur_channel_index)8534 QCameraReprocessChannel *QCamera2HardwareInterface::addReprocChannel(
8535         QCameraChannel *pInputChannel, int8_t cur_channel_index)
8536 {
8537     int32_t rc = NO_ERROR;
8538     QCameraReprocessChannel *pChannel = NULL;
8539     uint32_t burst_cnt = mParameters.getNumOfSnapshots();
8540     uint32_t pHandle = getCamHandleForChannel(QCAMERA_CH_TYPE_REPROCESSING);
8541 
8542     if (pInputChannel == NULL) {
8543         LOGE("input channel obj is NULL");
8544         return NULL;
8545     }
8546 
8547     pChannel = new QCameraReprocessChannel(pHandle, mCameraHandle->ops);
8548     if (NULL == pChannel) {
8549         LOGE("no mem for reprocess channel");
8550         return NULL;
8551     }
8552 
8553     // Capture channel, only need snapshot and postview streams start together
8554     mm_camera_channel_attr_t attr;
8555     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
8556     attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
8557     attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
8558     rc = pChannel->init(&attr,
8559                         postproc_channel_cb_routine,
8560                         this);
8561     if (rc != NO_ERROR) {
8562         LOGE("init reprocess channel failed, ret = %d", rc);
8563         delete pChannel;
8564         return NULL;
8565     }
8566 
8567     // pp feature config
8568     cam_pp_feature_config_t pp_config;
8569     memset(&pp_config, 0, sizeof(cam_pp_feature_config_t));
8570 
8571     rc = getPPConfig(pp_config, cur_channel_index,
8572             ((mParameters.getReprocCount() > 1) ? TRUE : FALSE));
8573     if (rc != NO_ERROR){
8574         LOGE("Error while creating PP config");
8575         delete pChannel;
8576         return NULL;
8577     }
8578 
8579     uint8_t minStreamBufNum = getBufNumRequired(CAM_STREAM_TYPE_OFFLINE_PROC);
8580 
8581     //WNR and HDR happen inline. No extra buffers needed.
8582     cam_feature_mask_t temp_feature_mask = pp_config.feature_mask;
8583     temp_feature_mask &= ~CAM_QCOM_FEATURE_HDR;
8584     if (temp_feature_mask && mParameters.isHDREnabled()) {
8585         minStreamBufNum = (uint8_t)(1 + mParameters.getNumOfExtraHDRInBufsIfNeeded());
8586     }
8587 
8588     if (mParameters.isStillMoreEnabled()) {
8589         cam_still_more_t stillmore_config = mParameters.getStillMoreSettings();
8590         pp_config.burst_cnt = stillmore_config.burst_count;
8591         LOGH("Stillmore burst %d", pp_config.burst_cnt);
8592 
8593         // getNumOfExtraBuffersForImageProc returns 1 less buffer assuming
8594         // number of capture is already added. In the case of liveshot,
8595         // stillmore burst is 1. This is to account for the premature decrement
8596         if (mParameters.getNumOfExtraBuffersForImageProc() == 0) {
8597             minStreamBufNum += 1;
8598         }
8599     }
8600 
8601     if (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_3) {
8602         minStreamBufNum += mParameters.getReprocCount() - 1;
8603         burst_cnt = mParameters.getReprocCount();
8604         if (cur_channel_index == 0) {
8605             pChannel->setReprocCount(2);
8606         } else {
8607             pChannel->setReprocCount(1);
8608         }
8609     } else {
8610         pChannel->setReprocCount(1);
8611     }
8612 
8613     if (isDualCamera() && mBundledSnapshot) {
8614         minStreamBufNum += 1;
8615     }
8616 
8617     // Add non inplace image lib buffers only when ppproc is present,
8618     // becuase pproc is non inplace and input buffers for img lib
8619     // are output for pproc and this number of extra buffers is required
8620     // If pproc is not there, input buffers for imglib are from snapshot stream
8621     uint8_t imglib_extra_bufs = mParameters.getNumOfExtraBuffersForImageProc();
8622     if (temp_feature_mask && imglib_extra_bufs) {
8623         // 1 is added because getNumOfExtraBuffersForImageProc returns extra
8624         // buffers assuming number of capture is already added
8625         minStreamBufNum = (uint8_t)(minStreamBufNum + imglib_extra_bufs + 1);
8626     }
8627 
8628     //Mask out features that are already processed in snapshot stream.
8629     cam_feature_mask_t snapshot_feature_mask = 0;
8630     mParameters.getStreamPpMask(CAM_STREAM_TYPE_SNAPSHOT, snapshot_feature_mask);
8631 
8632     pp_config.feature_mask &= ~snapshot_feature_mask;
8633     LOGH("Snapshot feature mask: 0x%llx, reproc feature mask: 0x%llx minStreamBufNum = %d",
8634             snapshot_feature_mask, pp_config.feature_mask, minStreamBufNum);
8635 
8636     bool offlineReproc = needOfflineReprocessing();
8637     if (m_postprocessor.mOfflineDataBufs != NULL) {
8638         offlineReproc = TRUE;
8639     }
8640 
8641     cam_padding_info_t paddingInfo = gCamCapability[mCameraId]->padding_info;
8642     paddingInfo.offset_info.offset_x = 0;
8643     paddingInfo.offset_info.offset_y = 0;
8644     rc = pChannel->addReprocStreamsFromSource(*this,
8645                                               pp_config,
8646                                               pInputChannel,
8647                                               minStreamBufNum,
8648                                               burst_cnt,
8649                                               &paddingInfo,
8650                                               mParameters,
8651                                               mLongshotEnabled,
8652                                               offlineReproc);
8653     if (rc != NO_ERROR) {
8654         delete pChannel;
8655         return NULL;
8656     }
8657 
8658     return pChannel;
8659 }
8660 
8661 /*===========================================================================
8662  * FUNCTION   : addOfflineReprocChannel
8663  *
8664  * DESCRIPTION: add a offline reprocess channel contains one reproc stream,
8665  *              that will do reprocess on frames coming from external images
8666  *
8667  * PARAMETERS :
8668  *   @img_config  : offline reporcess image info
8669  *   @pp_feature  : pp feature config
8670  *
8671  * RETURN     : int32_t type of status
8672  *              NO_ERROR  -- success
8673  *              none-zero failure code
8674  *==========================================================================*/
addOfflineReprocChannel(cam_pp_offline_src_config_t & img_config,cam_pp_feature_config_t & pp_feature,stream_cb_routine stream_cb,void * userdata)8675 QCameraReprocessChannel *QCamera2HardwareInterface::addOfflineReprocChannel(
8676                                             cam_pp_offline_src_config_t &img_config,
8677                                             cam_pp_feature_config_t &pp_feature,
8678                                             stream_cb_routine stream_cb,
8679                                             void *userdata)
8680 {
8681     int32_t rc = NO_ERROR;
8682     QCameraReprocessChannel *pChannel = NULL;
8683 
8684     pChannel = new QCameraReprocessChannel(mCameraHandle->camera_handle,
8685                                            mCameraHandle->ops);
8686     if (NULL == pChannel) {
8687         LOGE("no mem for reprocess channel");
8688         return NULL;
8689     }
8690 
8691     rc = pChannel->init(NULL, NULL, NULL);
8692     if (rc != NO_ERROR) {
8693         LOGE("init reprocess channel failed, ret = %d", rc);
8694         delete pChannel;
8695         return NULL;
8696     }
8697 
8698     QCameraHeapMemory *pStreamInfo = allocateStreamInfoBuf(CAM_STREAM_TYPE_OFFLINE_PROC);
8699     if (pStreamInfo == NULL) {
8700         LOGE("no mem for stream info buf");
8701         delete pChannel;
8702         return NULL;
8703     }
8704 
8705     cam_stream_info_t *streamInfoBuf = (cam_stream_info_t *)pStreamInfo->getPtr(0);
8706     memset(streamInfoBuf, 0, sizeof(cam_stream_info_t));
8707     streamInfoBuf->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC;
8708     streamInfoBuf->fmt = img_config.input_fmt;
8709     streamInfoBuf->dim = img_config.input_dim;
8710     streamInfoBuf->buf_planes = img_config.input_buf_planes;
8711     streamInfoBuf->streaming_mode = CAM_STREAMING_MODE_BURST;
8712     streamInfoBuf->num_of_burst = img_config.num_of_bufs;
8713 
8714     streamInfoBuf->reprocess_config.pp_type = CAM_OFFLINE_REPROCESS_TYPE;
8715     streamInfoBuf->reprocess_config.offline = img_config;
8716     streamInfoBuf->reprocess_config.pp_feature_config = pp_feature;
8717     streamInfoBuf->num_bufs = img_config.num_of_bufs;
8718 
8719     rc = pChannel->addStream(*this,
8720             pStreamInfo, NULL,
8721             &gCamCapability[mCameraId]->padding_info,
8722             stream_cb, userdata, false);
8723 
8724     if (rc != NO_ERROR) {
8725         LOGE("add reprocess stream failed, ret = %d", rc);
8726         delete pChannel;
8727         return NULL;
8728     }
8729 
8730     return pChannel;
8731 }
8732 
8733 /*===========================================================================
8734  * FUNCTION   : addChannel
8735  *
8736  * DESCRIPTION: add a channel by its type
8737  *
8738  * PARAMETERS :
8739  *   @ch_type : channel type
8740  *
8741  * RETURN     : int32_t type of status
8742  *              NO_ERROR  -- success
8743  *              none-zero failure code
8744  *==========================================================================*/
addChannel(qcamera_ch_type_enum_t ch_type)8745 int32_t QCamera2HardwareInterface::addChannel(qcamera_ch_type_enum_t ch_type)
8746 {
8747     int32_t rc = UNKNOWN_ERROR;
8748     switch (ch_type) {
8749     case QCAMERA_CH_TYPE_ZSL:
8750         rc = addZSLChannel();
8751         break;
8752     case QCAMERA_CH_TYPE_CAPTURE:
8753         rc = addCaptureChannel();
8754         break;
8755     case QCAMERA_CH_TYPE_PREVIEW:
8756         rc = addPreviewChannel();
8757         break;
8758     case QCAMERA_CH_TYPE_VIDEO:
8759         rc = addVideoChannel();
8760         break;
8761     case QCAMERA_CH_TYPE_SNAPSHOT:
8762         rc = addSnapshotChannel();
8763         break;
8764     case QCAMERA_CH_TYPE_RAW:
8765         rc = addRawChannel();
8766         break;
8767     case QCAMERA_CH_TYPE_METADATA:
8768         rc = addMetaDataChannel();
8769         break;
8770     case QCAMERA_CH_TYPE_CALLBACK:
8771         rc = addCallbackChannel();
8772         break;
8773     case QCAMERA_CH_TYPE_ANALYSIS:
8774         rc = addAnalysisChannel();
8775         break;
8776     default:
8777         break;
8778     }
8779     return rc;
8780 }
8781 
8782 /*===========================================================================
8783  * FUNCTION   : delChannel
8784  *
8785  * DESCRIPTION: delete a channel by its type
8786  *
8787  * PARAMETERS :
8788  *   @ch_type : channel type
8789  *   @destroy : delete context as well
8790  *
8791  * RETURN     : int32_t type of status
8792  *              NO_ERROR  -- success
8793  *              none-zero failure code
8794  *==========================================================================*/
delChannel(qcamera_ch_type_enum_t ch_type,bool destroy)8795 int32_t QCamera2HardwareInterface::delChannel(qcamera_ch_type_enum_t ch_type,
8796                                               bool destroy)
8797 {
8798     if (m_channels[ch_type] != NULL) {
8799         if (destroy) {
8800             delete m_channels[ch_type];
8801             m_channels[ch_type] = NULL;
8802         } else {
8803             m_channels[ch_type]->deleteChannel();
8804         }
8805     }
8806 
8807     return NO_ERROR;
8808 }
8809 
8810 /*===========================================================================
8811  * FUNCTION   : startChannel
8812  *
8813  * DESCRIPTION: start a channel by its type
8814  *
8815  * PARAMETERS :
8816  *   @ch_type : channel type
8817  *
8818  * RETURN     : int32_t type of status
8819  *              NO_ERROR  -- success
8820  *              none-zero failure code
8821  *==========================================================================*/
startChannel(qcamera_ch_type_enum_t ch_type)8822 int32_t QCamera2HardwareInterface::startChannel(qcamera_ch_type_enum_t ch_type)
8823 {
8824     int32_t rc = UNKNOWN_ERROR;
8825     if (m_channels[ch_type] != NULL) {
8826         rc = m_channels[ch_type]->start();
8827     }
8828     return rc;
8829 }
8830 
8831 /*===========================================================================
8832  * FUNCTION   : stopChannel
8833  *
8834  * DESCRIPTION: stop a channel by its type
8835  *
8836  * PARAMETERS :
8837  *   @ch_type : channel type
8838  *
8839  * RETURN     : int32_t type of status
8840  *              NO_ERROR  -- success
8841  *              none-zero failure code
8842  *==========================================================================*/
stopChannel(qcamera_ch_type_enum_t ch_type)8843 int32_t QCamera2HardwareInterface::stopChannel(qcamera_ch_type_enum_t ch_type)
8844 {
8845     int32_t rc = UNKNOWN_ERROR;
8846     if (m_channels[ch_type] != NULL) {
8847         rc = m_channels[ch_type]->stop();
8848     }
8849 
8850     return rc;
8851 }
8852 
8853 /*===========================================================================
8854  * FUNCTION   : preparePreview
8855  *
8856  * DESCRIPTION: add channels needed for preview
8857  *
8858  * PARAMETERS : none
8859  *
8860  * RETURN     : int32_t type of status
8861  *              NO_ERROR  -- success
8862  *              none-zero failure code
8863  *==========================================================================*/
preparePreview()8864 int32_t QCamera2HardwareInterface::preparePreview()
8865 {
8866     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PREPAREPREVIEW);
8867     int32_t rc = NO_ERROR;
8868 
8869     LOGI("E");
8870     rc = mParameters.setStreamConfigure(false, false, false);
8871     if (rc != NO_ERROR) {
8872         LOGE("setStreamConfigure failed %d", rc);
8873         return rc;
8874     }
8875 
8876     //Trigger deferred job second camera
8877     if (isDualCamera()) {
8878         mParameters.setDeferCamera(CAM_DEFER_START);
8879     }
8880 
8881     if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) {
8882         rc = addChannel(QCAMERA_CH_TYPE_ZSL);
8883         if (rc != NO_ERROR) {
8884             LOGE("failed!! rc = %d", rc);
8885             return rc;
8886         }
8887 
8888         if (mParameters.isUBWCEnabled()) {
8889             cam_format_t fmt;
8890             mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW, fmt);
8891             if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
8892                 rc = addChannel(QCAMERA_CH_TYPE_CALLBACK);
8893                 if (rc != NO_ERROR) {
8894                     delChannel(QCAMERA_CH_TYPE_ZSL);
8895                     LOGE("failed!! rc = %d", rc);
8896                     return rc;
8897                 }
8898             }
8899         }
8900 
8901         if (mParameters.getofflineRAW() && !mParameters.getQuadraCfa()) {
8902             addChannel(QCAMERA_CH_TYPE_RAW);
8903         }
8904     } else if(isSecureMode()) {
8905         if (mParameters.getSecureStreamType() == CAM_STREAM_TYPE_RAW) {
8906             rc = addChannel(QCAMERA_CH_TYPE_RAW);
8907         } else {
8908             rc = addChannel(QCAMERA_CH_TYPE_PREVIEW);
8909         }
8910     } else {
8911         bool recordingHint = mParameters.getRecordingHintValue();
8912         if(!isRdiMode() && recordingHint) {
8913             //stop face detection,longshot,etc if turned ON in Camera mode
8914 #ifndef VANILLA_HAL
8915             int32_t arg; //dummy arg
8916             if (isLongshotEnabled()) {
8917                 sendCommand(CAMERA_CMD_LONGSHOT_OFF, arg, arg);
8918             }
8919             if (mParameters.isFaceDetectionEnabled()
8920                     && (!mParameters.fdModeInVideo())) {
8921                 sendCommand(CAMERA_CMD_STOP_FACE_DETECTION, arg, arg);
8922             }
8923             if (mParameters.isHistogramEnabled()) {
8924                 sendCommand(CAMERA_CMD_HISTOGRAM_OFF, arg, arg);
8925             }
8926 #endif
8927             //Don't create snapshot channel for liveshot, if low power mode is set.
8928             //Use video stream instead.
8929             if (!isLowPowerMode()) {
8930                rc = addChannel(QCAMERA_CH_TYPE_SNAPSHOT);
8931                if (rc != NO_ERROR) {
8932                    return rc;
8933                }
8934             }
8935 
8936             rc = addChannel(QCAMERA_CH_TYPE_VIDEO);
8937             if (rc != NO_ERROR) {
8938                 delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
8939                 LOGE("failed!! rc = %d", rc);
8940                 return rc;
8941             }
8942         }
8943 
8944         rc = addChannel(QCAMERA_CH_TYPE_PREVIEW);
8945         if (!isRdiMode() && (rc != NO_ERROR)) {
8946             if (recordingHint) {
8947                 delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
8948                 delChannel(QCAMERA_CH_TYPE_VIDEO);
8949             }
8950         }
8951 
8952         if (mParameters.isUBWCEnabled() && !recordingHint) {
8953             cam_format_t fmt;
8954             mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW, fmt);
8955             if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
8956                 rc = addChannel(QCAMERA_CH_TYPE_CALLBACK);
8957                 if (rc != NO_ERROR) {
8958                     delChannel(QCAMERA_CH_TYPE_PREVIEW);
8959                     if (!isRdiMode()) {
8960                         delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
8961                         delChannel(QCAMERA_CH_TYPE_VIDEO);
8962                     }
8963                     LOGE("failed!! rc = %d", rc);
8964                     return rc;
8965                 }
8966             }
8967         }
8968 
8969         if (NO_ERROR != rc) {
8970             delChannel(QCAMERA_CH_TYPE_PREVIEW);
8971             LOGE("failed!! rc = %d", rc);
8972         }
8973     }
8974 
8975     if ((rc != NO_ERROR) && (isDualCamera())) {
8976         mParameters.setDeferCamera(CAM_DEFER_FLUSH);
8977     }
8978 
8979     LOGI("X rc = %d", rc);
8980     return rc;
8981 }
8982 
8983 /*===========================================================================
8984  * FUNCTION   : unpreparePreview
8985  *
8986  * DESCRIPTION: delete channels for preview
8987  *
8988  * PARAMETERS : none
8989  *
8990  * RETURN     : none
8991  *==========================================================================*/
unpreparePreview()8992 void QCamera2HardwareInterface::unpreparePreview()
8993 {
8994     if (isDualCamera()) {
8995         mParameters.setDeferCamera(CAM_DEFER_FLUSH);
8996     }
8997     delChannel(QCAMERA_CH_TYPE_ZSL);
8998     delChannel(QCAMERA_CH_TYPE_PREVIEW);
8999     delChannel(QCAMERA_CH_TYPE_VIDEO);
9000     delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
9001     delChannel(QCAMERA_CH_TYPE_CALLBACK);
9002     delChannel(QCAMERA_CH_TYPE_RAW);
9003 }
9004 
9005 /*===========================================================================
9006  * FUNCTION   : playShutter
9007  *
9008  * DESCRIPTION: send request to play shutter sound
9009  *
9010  * PARAMETERS : none
9011  *
9012  * RETURN     : none
9013  *==========================================================================*/
playShutter()9014 void QCamera2HardwareInterface::playShutter(){
9015      if (mNotifyCb == NULL ||
9016          msgTypeEnabledWithLock(CAMERA_MSG_SHUTTER) == 0){
9017          LOGD("shutter msg not enabled or NULL cb");
9018          return;
9019      }
9020      LOGH("CAMERA_MSG_SHUTTER ");
9021      qcamera_callback_argm_t cbArg;
9022      memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
9023      cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK;
9024      cbArg.msg_type = CAMERA_MSG_SHUTTER;
9025      cbArg.ext1 = 0;
9026      cbArg.ext2 = false;
9027      m_cbNotifier.notifyCallback(cbArg);
9028 }
9029 
9030 /*===========================================================================
9031  * FUNCTION   : getChannelByHandle
9032  *
9033  * DESCRIPTION: return a channel by its handle
9034  *
9035  * PARAMETERS :
9036  *   @channelHandle : channel handle
9037  *
9038  * RETURN     : a channel obj if found, NULL if not found
9039  *==========================================================================*/
getChannelByHandle(uint32_t channelHandle)9040 QCameraChannel *QCamera2HardwareInterface::getChannelByHandle(uint32_t channelHandle)
9041 {
9042     for(int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
9043         if (m_channels[i] != NULL &&
9044             (validate_handle(m_channels[i]->getMyHandle(), channelHandle))) {
9045             return m_channels[i];
9046         }
9047     }
9048 
9049     return NULL;
9050 }
9051 /*===========================================================================
9052  * FUNCTION   : needPreviewFDCallback
9053  *
9054  * DESCRIPTION: decides if needPreviewFDCallback
9055  *
9056  * PARAMETERS :
9057  *   @num_faces : number of faces
9058  *
9059  * RETURN     : bool type of status
9060  *              true  -- success
9061  *              fale -- failure code
9062  *==========================================================================*/
needPreviewFDCallback(uint8_t num_faces)9063 bool QCamera2HardwareInterface::needPreviewFDCallback(uint8_t num_faces)
9064 {
9065     if (num_faces == 0 && mNumPreviewFaces == 0) {
9066         return false;
9067     }
9068 
9069     return true;
9070 }
9071 
9072 /*===========================================================================
9073  * FUNCTION   : processFaceDetectionReuslt
9074  *
9075  * DESCRIPTION: process face detection reuslt
9076  *
9077  * PARAMETERS :
9078  *   @faces_data : ptr to face processing result struct
9079  *
9080  * RETURN     : int32_t type of status
9081  *              NO_ERROR  -- success
9082  *              none-zero failure code
9083  *==========================================================================*/
processFaceDetectionResult(cam_faces_data_t * faces_data)9084 int32_t QCamera2HardwareInterface::processFaceDetectionResult(cam_faces_data_t *faces_data)
9085 {
9086     if (!mParameters.isFaceDetectionEnabled()) {
9087         LOGH("FaceDetection not enabled, no ops here");
9088         return NO_ERROR;
9089     }
9090 
9091     qcamera_face_detect_type_t fd_type = faces_data->detection_data.fd_type;
9092     cam_face_detection_data_t *detect_data = &(faces_data->detection_data);
9093     if ((NULL == mDataCb) ||
9094         (fd_type == QCAMERA_FD_PREVIEW && !msgTypeEnabled(CAMERA_MSG_PREVIEW_METADATA)) ||
9095         (!needPreviewFDCallback(detect_data->num_faces_detected))
9096 #ifndef VANILLA_HAL
9097         || (fd_type == QCAMERA_FD_SNAPSHOT && !msgTypeEnabled(CAMERA_MSG_META_DATA))
9098 #endif
9099         ) {
9100         LOGH("metadata msgtype not enabled, no ops here");
9101         return NO_ERROR;
9102     }
9103 
9104     if ((fd_type == QCAMERA_FD_PREVIEW) && (detect_data->update_flag == FALSE)) {
9105         // Don't send callback to app if this is skipped by fd at backend
9106         return NO_ERROR;
9107     }
9108 
9109     cam_dimension_t display_dim;
9110     mParameters.getStreamDimension(CAM_STREAM_TYPE_PREVIEW, display_dim);
9111     if (display_dim.width <= 0 || display_dim.height <= 0) {
9112         LOGE("Invalid preview width or height (%d x %d)",
9113                display_dim.width, display_dim.height);
9114         return UNKNOWN_ERROR;
9115     }
9116 
9117     // process face detection result
9118     // need separate face detection in preview or snapshot type
9119     size_t faceResultSize = 0;
9120     size_t data_len = 0;
9121     if(fd_type == QCAMERA_FD_PREVIEW){
9122         //fd for preview frames
9123         faceResultSize = sizeof(camera_frame_metadata_t);
9124         faceResultSize += sizeof(camera_face_t) * MAX_ROI;
9125     }else if(fd_type == QCAMERA_FD_SNAPSHOT){
9126 #ifndef VANILLA_HAL
9127         // fd for snapshot frames
9128         //check if face is detected in this frame
9129         if(detect_data->num_faces_detected > 0){
9130             data_len = sizeof(camera_frame_metadata_t) +
9131                     sizeof(camera_face_t) * detect_data->num_faces_detected;
9132         }else{
9133             //no face
9134             data_len = 0;
9135         }
9136 #endif
9137         faceResultSize = 1 *sizeof(int)    //meta data type
9138                        + 1 *sizeof(int)    // meta data len
9139                        + data_len;         //data
9140     }
9141 
9142     camera_memory_t *faceResultBuffer = mGetMemory(-1,
9143                                                    faceResultSize,
9144                                                    1,
9145                                                    mCallbackCookie);
9146     if ( NULL == faceResultBuffer ) {
9147         LOGE("Not enough memory for face result data");
9148         return NO_MEMORY;
9149     }
9150 
9151     unsigned char *pFaceResult = ( unsigned char * ) faceResultBuffer->data;
9152     memset(pFaceResult, 0, faceResultSize);
9153     unsigned char *faceData = NULL;
9154     if(fd_type == QCAMERA_FD_PREVIEW){
9155         faceData = pFaceResult;
9156         mNumPreviewFaces = detect_data->num_faces_detected;
9157     }else if(fd_type == QCAMERA_FD_SNAPSHOT){
9158 #ifndef VANILLA_HAL
9159         //need fill meta type and meta data len first
9160         int *data_header = (int* )pFaceResult;
9161         data_header[0] = CAMERA_META_DATA_FD;
9162         data_header[1] = (int)data_len;
9163 
9164         if(data_len <= 0){
9165             //if face is not valid or do not have face, return
9166             qcamera_callback_argm_t cbArg;
9167             memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
9168             cbArg.cb_type = QCAMERA_DATA_CALLBACK;
9169             cbArg.msg_type = CAMERA_MSG_META_DATA;
9170             cbArg.data = faceResultBuffer;
9171             cbArg.user_data = faceResultBuffer;
9172             cbArg.cookie = this;
9173             cbArg.release_cb = releaseCameraMemory;
9174             int32_t rc = m_cbNotifier.notifyCallback(cbArg);
9175             if (rc != NO_ERROR) {
9176                 LOGE("fail sending notification");
9177                 faceResultBuffer->release(faceResultBuffer);
9178             }
9179             return rc;
9180         }
9181 #endif
9182         faceData = pFaceResult + 2 *sizeof(int); //skip two int length
9183     }
9184 
9185     camera_frame_metadata_t *roiData = (camera_frame_metadata_t * ) faceData;
9186     camera_face_t *faces = (camera_face_t *) ( faceData + sizeof(camera_frame_metadata_t) );
9187 
9188     roiData->number_of_faces = detect_data->num_faces_detected;
9189     roiData->faces = faces;
9190     LOGL("FD_DEBUG : Frame[%d] : number_of_faces=%d, display_dim=%d %d",
9191             detect_data->frame_id, detect_data->num_faces_detected,
9192             display_dim.width, display_dim.height);
9193     if (roiData->number_of_faces > 0) {
9194         for (int i = 0; i < roiData->number_of_faces; i++) {
9195             faces[i].id = detect_data->faces[i].face_id;
9196             faces[i].score = detect_data->faces[i].score;
9197 
9198             // left
9199             faces[i].rect[0] = MAP_TO_DRIVER_COORDINATE(
9200                     detect_data->faces[i].face_boundary.left,
9201                     display_dim.width, 2000, -1000);
9202 
9203             // top
9204             faces[i].rect[1] = MAP_TO_DRIVER_COORDINATE(
9205                     detect_data->faces[i].face_boundary.top,
9206                     display_dim.height, 2000, -1000);
9207 
9208             // right
9209             faces[i].rect[2] = faces[i].rect[0] +
9210                     MAP_TO_DRIVER_COORDINATE(
9211                     detect_data->faces[i].face_boundary.width,
9212                     display_dim.width, 2000, 0);
9213 
9214              // bottom
9215             faces[i].rect[3] = faces[i].rect[1] +
9216                     MAP_TO_DRIVER_COORDINATE(
9217                     detect_data->faces[i].face_boundary.height,
9218                     display_dim.height, 2000, 0);
9219 
9220             LOGL("FD_DEBUG : Frame[%d] : Face[%d] : id=%d, score=%d, "
9221                     "CAM[left=%d, top=%d, w=%d, h=%d], "
9222                     "APP[left=%d, top=%d, right=%d, bottom=%d] ",
9223                     detect_data->frame_id, i, faces[i].id, faces[i].score,
9224                     detect_data->faces[i].face_boundary.left,
9225                     detect_data->faces[i].face_boundary.top,
9226                     detect_data->faces[i].face_boundary.width,
9227                     detect_data->faces[i].face_boundary.height,
9228                     faces[i].rect[0], faces[i].rect[1],
9229                     faces[i].rect[2], faces[i].rect[3]);
9230 
9231             if (faces_data->landmark_valid) {
9232                 // Center of left eye
9233                 if (faces_data->landmark_data.face_landmarks[i].is_left_eye_valid) {
9234                     faces[i].left_eye[0] = MAP_TO_DRIVER_COORDINATE(
9235                             faces_data->landmark_data.face_landmarks[i].left_eye_center.x,
9236                             display_dim.width, 2000, -1000);
9237                     faces[i].left_eye[1] = MAP_TO_DRIVER_COORDINATE(
9238                             faces_data->landmark_data.face_landmarks[i].left_eye_center.y,
9239                             display_dim.height, 2000, -1000);
9240                 } else {
9241                     faces[i].left_eye[0] = FACE_INVALID_POINT;
9242                     faces[i].left_eye[1] = FACE_INVALID_POINT;
9243                 }
9244 
9245                 // Center of right eye
9246                 if (faces_data->landmark_data.face_landmarks[i].is_right_eye_valid) {
9247                     faces[i].right_eye[0] = MAP_TO_DRIVER_COORDINATE(
9248                             faces_data->landmark_data.face_landmarks[i].right_eye_center.x,
9249                             display_dim.width, 2000, -1000);
9250                     faces[i].right_eye[1] = MAP_TO_DRIVER_COORDINATE(
9251                             faces_data->landmark_data.face_landmarks[i].right_eye_center.y,
9252                             display_dim.height, 2000, -1000);
9253                 } else {
9254                     faces[i].right_eye[0] = FACE_INVALID_POINT;
9255                     faces[i].right_eye[1] = FACE_INVALID_POINT;
9256                 }
9257 
9258                 // Center of mouth
9259                 if (faces_data->landmark_data.face_landmarks[i].is_mouth_valid) {
9260                     faces[i].mouth[0] = MAP_TO_DRIVER_COORDINATE(
9261                             faces_data->landmark_data.face_landmarks[i].mouth_center.x,
9262                             display_dim.width, 2000, -1000);
9263                     faces[i].mouth[1] = MAP_TO_DRIVER_COORDINATE(
9264                             faces_data->landmark_data.face_landmarks[i].mouth_center.y,
9265                             display_dim.height, 2000, -1000);
9266                 } else {
9267                     faces[i].mouth[0] = FACE_INVALID_POINT;
9268                     faces[i].mouth[1] = FACE_INVALID_POINT;
9269                 }
9270 
9271                 LOGL("FD_DEBUG LANDMARK : Frame[%d] : Face[%d] : "
9272                         "eye : left(%d, %d) right(%d, %d), mouth(%d, %d)",
9273                         detect_data->frame_id, i, faces[i].left_eye[0], faces[i].left_eye[1],
9274                         faces[i].right_eye[0], faces[i].right_eye[1],
9275                         faces[i].mouth[0], faces[i].mouth[1]);
9276             } else {
9277                 // return -2000 if invalid
9278                 faces[i].left_eye[0] = FACE_INVALID_POINT;
9279                 faces[i].left_eye[1] = FACE_INVALID_POINT;
9280 
9281                 faces[i].right_eye[0] = FACE_INVALID_POINT;
9282                 faces[i].right_eye[1] = FACE_INVALID_POINT;
9283 
9284                 faces[i].mouth[0] = FACE_INVALID_POINT;
9285                 faces[i].mouth[1] = FACE_INVALID_POINT;
9286             }
9287 
9288 #ifndef VANILLA_HAL
9289 #ifdef TARGET_TS_MAKEUP
9290             mFaceRect.left = detect_data->faces[i].face_boundary.left;
9291             mFaceRect.top = detect_data->faces[i].face_boundary.top;
9292             mFaceRect.right = detect_data->faces[i].face_boundary.width+mFaceRect.left;
9293             mFaceRect.bottom = detect_data->faces[i].face_boundary.height+mFaceRect.top;
9294 #endif
9295             if (faces_data->smile_valid) {
9296                 faces[i].smile_degree = faces_data->smile_data.smile[i].smile_degree;
9297                 faces[i].smile_score = faces_data->smile_data.smile[i].smile_confidence;
9298 
9299                 LOGL("FD_DEBUG LANDMARK : Frame[%d] : Face[%d] : smile_degree=%d, smile_score=%d",
9300                         detect_data->frame_id, i, faces[i].smile_degree, faces[i].smile_score);
9301             }
9302             if (faces_data->blink_valid) {
9303                 faces[i].blink_detected = faces_data->blink_data.blink[i].blink_detected;
9304                 faces[i].leye_blink = faces_data->blink_data.blink[i].left_blink;
9305                 faces[i].reye_blink = faces_data->blink_data.blink[i].right_blink;
9306 
9307                 LOGL("FD_DEBUG LANDMARK : Frame[%d] : Face[%d] : "
9308                         "blink_detected=%d, leye_blink=%d, reye_blink=%d",
9309                         detect_data->frame_id, i, faces[i].blink_detected, faces[i].leye_blink,
9310                         faces[i].reye_blink);
9311             }
9312             if (faces_data->recog_valid) {
9313                 faces[i].face_recognised = faces_data->recog_data.face_rec[i].face_recognised;
9314 
9315                 LOGL("FD_DEBUG LANDMARK : Frame[%d] : Face[%d] : face_recognised=%d",
9316                         detect_data->frame_id, i, faces[i].face_recognised);
9317             }
9318             if (faces_data->gaze_valid) {
9319                 faces[i].gaze_angle = faces_data->gaze_data.gaze[i].gaze_angle;
9320                 faces[i].updown_dir = faces_data->gaze_data.gaze[i].updown_dir;
9321                 faces[i].leftright_dir = faces_data->gaze_data.gaze[i].leftright_dir;
9322                 faces[i].roll_dir = faces_data->gaze_data.gaze[i].roll_dir;
9323                 faces[i].left_right_gaze = faces_data->gaze_data.gaze[i].left_right_gaze;
9324                 faces[i].top_bottom_gaze = faces_data->gaze_data.gaze[i].top_bottom_gaze;
9325 
9326                 LOGL("FD_DEBUG LANDMARK : Frame[%d] : Face[%d] : gaze_angle=%d, updown_dir=%d, "
9327                         "leftright_dir=%d,, roll_dir=%d, left_right_gaze=%d, top_bottom_gaze=%d",
9328                         detect_data->frame_id, i, faces[i].gaze_angle, faces[i].updown_dir,
9329                         faces[i].leftright_dir, faces[i].roll_dir, faces[i].left_right_gaze,
9330                         faces[i].top_bottom_gaze);
9331             }
9332 #endif
9333 
9334         }
9335     }
9336     else{
9337 #ifdef TARGET_TS_MAKEUP
9338         memset(&mFaceRect,-1,sizeof(mFaceRect));
9339 #endif
9340     }
9341     qcamera_callback_argm_t cbArg;
9342     memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
9343     cbArg.cb_type = QCAMERA_DATA_CALLBACK;
9344     if(fd_type == QCAMERA_FD_PREVIEW){
9345         cbArg.msg_type = CAMERA_MSG_PREVIEW_METADATA;
9346     }
9347 #ifndef VANILLA_HAL
9348     else if(fd_type == QCAMERA_FD_SNAPSHOT){
9349         cbArg.msg_type = CAMERA_MSG_META_DATA;
9350     }
9351 #endif
9352     cbArg.data = faceResultBuffer;
9353     cbArg.metadata = roiData;
9354     cbArg.user_data = faceResultBuffer;
9355     cbArg.cookie = this;
9356     cbArg.release_cb = releaseCameraMemory;
9357     int32_t rc = m_cbNotifier.notifyCallback(cbArg);
9358     if (rc != NO_ERROR) {
9359         LOGE("fail sending notification");
9360         faceResultBuffer->release(faceResultBuffer);
9361     }
9362 
9363     return rc;
9364 }
9365 
9366 /*===========================================================================
9367  * FUNCTION   : releaseCameraMemory
9368  *
9369  * DESCRIPTION: releases camera memory objects
9370  *
9371  * PARAMETERS :
9372  *   @data    : buffer to be released
9373  *   @cookie  : context data
9374  *   @cbStatus: callback status
9375  *
9376  * RETURN     : None
9377  *==========================================================================*/
releaseCameraMemory(void * data,void *,int32_t)9378 void QCamera2HardwareInterface::releaseCameraMemory(void *data,
9379                                                     void */*cookie*/,
9380                                                     int32_t /*cbStatus*/)
9381 {
9382     camera_memory_t *mem = ( camera_memory_t * ) data;
9383     if ( NULL != mem ) {
9384         mem->release(mem);
9385     }
9386 }
9387 
9388 /*===========================================================================
9389  * FUNCTION   : returnStreamBuffer
9390  *
9391  * DESCRIPTION: returns back a stream buffer
9392  *
9393  * PARAMETERS :
9394  *   @data    : buffer to be released
9395  *   @cookie  : context data
9396  *   @cbStatus: callback status
9397  *
9398  * RETURN     : None
9399  *==========================================================================*/
returnStreamBuffer(void * data,void * cookie,int32_t)9400 void QCamera2HardwareInterface::returnStreamBuffer(void *data,
9401                                                    void *cookie,
9402                                                    int32_t /*cbStatus*/)
9403 {
9404     QCameraStream *stream = ( QCameraStream * ) cookie;
9405     int idx = *((int *)data);
9406     if ((NULL != stream) && (0 <= idx)) {
9407         stream->bufDone((uint32_t)idx);
9408     } else {
9409         LOGE("Cannot return buffer %d %p", idx, cookie);
9410     }
9411 }
9412 
9413 /*===========================================================================
9414  * FUNCTION   : processHistogramStats
9415  *
9416  * DESCRIPTION: process histogram stats
9417  *
9418  * PARAMETERS :
9419  *   @hist_data : ptr to histogram stats struct
9420  *
9421  * RETURN     : int32_t type of status
9422  *              NO_ERROR  -- success
9423  *              none-zero failure code
9424  *==========================================================================*/
processHistogramStats(__unused cam_hist_stats_t & stats_data)9425 int32_t QCamera2HardwareInterface::processHistogramStats(
9426         __unused cam_hist_stats_t &stats_data)
9427 {
9428 #ifndef VANILLA_HAL
9429     if (!mParameters.isHistogramEnabled()) {
9430         LOGH("Histogram not enabled, no ops here");
9431         return NO_ERROR;
9432     }
9433 
9434     camera_memory_t *histBuffer = mGetMemory(-1,
9435                                              sizeof(cam_histogram_data_t),
9436                                              1,
9437                                              mCallbackCookie);
9438     if ( NULL == histBuffer ) {
9439         LOGE("Not enough memory for histogram data");
9440         return NO_MEMORY;
9441     }
9442 
9443     cam_histogram_data_t *pHistData = (cam_histogram_data_t *)histBuffer->data;
9444     if (pHistData == NULL) {
9445         LOGE("memory data ptr is NULL");
9446         return UNKNOWN_ERROR;
9447     }
9448 
9449     switch (stats_data.type) {
9450     case CAM_HISTOGRAM_TYPE_BAYER:
9451         switch (stats_data.bayer_stats.data_type) {
9452             case CAM_STATS_CHANNEL_Y:
9453             case CAM_STATS_CHANNEL_R:
9454                 *pHistData = stats_data.bayer_stats.r_stats;
9455                 break;
9456             case CAM_STATS_CHANNEL_GR:
9457                 *pHistData = stats_data.bayer_stats.gr_stats;
9458                 break;
9459             case CAM_STATS_CHANNEL_GB:
9460             case CAM_STATS_CHANNEL_ALL:
9461                 *pHistData = stats_data.bayer_stats.gb_stats;
9462                 break;
9463             case CAM_STATS_CHANNEL_B:
9464                 *pHistData = stats_data.bayer_stats.b_stats;
9465                 break;
9466             default:
9467                 *pHistData = stats_data.bayer_stats.r_stats;
9468                 break;
9469         }
9470         break;
9471     case CAM_HISTOGRAM_TYPE_YUV:
9472         *pHistData = stats_data.yuv_stats;
9473         break;
9474     }
9475 
9476     qcamera_callback_argm_t cbArg;
9477     memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
9478     cbArg.cb_type = QCAMERA_DATA_CALLBACK;
9479     cbArg.msg_type = CAMERA_MSG_STATS_DATA;
9480     cbArg.data = histBuffer;
9481     cbArg.user_data = histBuffer;
9482     cbArg.cookie = this;
9483     cbArg.release_cb = releaseCameraMemory;
9484     int32_t rc = m_cbNotifier.notifyCallback(cbArg);
9485     if (rc != NO_ERROR) {
9486         LOGE("fail sending notification");
9487         histBuffer->release(histBuffer);
9488     }
9489 #endif
9490     return NO_ERROR;
9491 }
9492 
9493 /*===========================================================================
9494  * FUNCTION   : calcThermalLevel
9495  *
9496  * DESCRIPTION: Calculates the target fps range depending on
9497  *              the thermal level.
9498  *              Note that this function can be called from QCameraParametersIntf
9499  *              while mutex is held. So it should not call back into
9500  *              QCameraParametersIntf causing deadlock.
9501  *
9502  * PARAMETERS :
9503  *   @level      : received thermal level
9504  *   @minFPS     : minimum configured fps range
9505  *   @maxFPS     : maximum configured fps range
9506  *   @minVideoFps: minimum configured fps range
9507  *   @maxVideoFps: maximum configured fps range
9508  *   @adjustedRange : target fps range
9509  *   @skipPattern : target skip pattern
9510  *   @bRecordingHint : recording hint value
9511  *
9512  * RETURN     : int32_t type of status
9513  *              NO_ERROR  -- success
9514  *              none-zero failure code
9515  *==========================================================================*/
calcThermalLevel(qcamera_thermal_level_enum_t level,const int minFPSi,const int maxFPSi,const float & minVideoFps,const float & maxVideoFps,cam_fps_range_t & adjustedRange,enum msm_vfe_frame_skip_pattern & skipPattern,bool bRecordingHint)9516 int QCamera2HardwareInterface::calcThermalLevel(
9517             qcamera_thermal_level_enum_t level,
9518             const int minFPSi,
9519             const int maxFPSi,
9520             const float &minVideoFps,
9521             const float &maxVideoFps,
9522             cam_fps_range_t &adjustedRange,
9523             enum msm_vfe_frame_skip_pattern &skipPattern,
9524             bool bRecordingHint)
9525 {
9526     const float minFPS = (float)minFPSi;
9527     const float maxFPS = (float)maxFPSi;
9528 
9529     LOGH("level: %d, preview minfps %f, preview maxfpS %f, "
9530               "video minfps %f, video maxfpS %f",
9531              level, minFPS, maxFPS, minVideoFps, maxVideoFps);
9532 
9533     switch(level) {
9534     case QCAMERA_THERMAL_NO_ADJUSTMENT:
9535         {
9536             adjustedRange.min_fps = minFPS / 1000.0f;
9537             adjustedRange.max_fps = maxFPS / 1000.0f;
9538             adjustedRange.video_min_fps = minVideoFps / 1000.0f;
9539             adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
9540             skipPattern = NO_SKIP;
9541         }
9542         break;
9543     case QCAMERA_THERMAL_SLIGHT_ADJUSTMENT:
9544         {
9545             adjustedRange.min_fps = minFPS / 1000.0f;
9546             adjustedRange.max_fps = maxFPS / 1000.0f;
9547             adjustedRange.min_fps -= 0.1f * adjustedRange.min_fps;
9548             adjustedRange.max_fps -= 0.1f * adjustedRange.max_fps;
9549             adjustedRange.video_min_fps = minVideoFps / 1000.0f;
9550             adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
9551             adjustedRange.video_min_fps -= 0.1f * adjustedRange.video_min_fps;
9552             adjustedRange.video_max_fps -= 0.1f * adjustedRange.video_max_fps;
9553             if ( adjustedRange.min_fps < 1 ) {
9554                 adjustedRange.min_fps = 1;
9555             }
9556             if ( adjustedRange.max_fps < 1 ) {
9557                 adjustedRange.max_fps = 1;
9558             }
9559             if ( adjustedRange.video_min_fps < 1 ) {
9560                 adjustedRange.video_min_fps = 1;
9561             }
9562             if ( adjustedRange.video_max_fps < 1 ) {
9563                 adjustedRange.video_max_fps = 1;
9564             }
9565             skipPattern = EVERY_2FRAME;
9566         }
9567         break;
9568     case QCAMERA_THERMAL_BIG_ADJUSTMENT:
9569         {
9570             adjustedRange.min_fps = minFPS / 1000.0f;
9571             adjustedRange.max_fps = maxFPS / 1000.0f;
9572             adjustedRange.min_fps -= 0.2f * adjustedRange.min_fps;
9573             adjustedRange.max_fps -= 0.2f * adjustedRange.max_fps;
9574             adjustedRange.video_min_fps = minVideoFps / 1000.0f;
9575             adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
9576             adjustedRange.video_min_fps -= 0.2f * adjustedRange.video_min_fps;
9577             adjustedRange.video_max_fps -= 0.2f * adjustedRange.video_max_fps;
9578             if ( adjustedRange.min_fps < 1 ) {
9579                 adjustedRange.min_fps = 1;
9580             }
9581             if ( adjustedRange.max_fps < 1 ) {
9582                 adjustedRange.max_fps = 1;
9583             }
9584             if ( adjustedRange.video_min_fps < 1 ) {
9585                 adjustedRange.video_min_fps = 1;
9586             }
9587             if ( adjustedRange.video_max_fps < 1 ) {
9588                 adjustedRange.video_max_fps = 1;
9589             }
9590             skipPattern = EVERY_4FRAME;
9591         }
9592         break;
9593     case QCAMERA_THERMAL_MAX_ADJUSTMENT:
9594         {
9595             // Stop Preview?
9596             // Set lowest min FPS for now
9597             adjustedRange.min_fps = minFPS/1000.0f;
9598             adjustedRange.max_fps = minFPS/1000.0f;
9599             cam_capability_t *capability = gCamCapability[mCameraId];
9600             for (size_t i = 0;
9601                      i < capability->fps_ranges_tbl_cnt;
9602                      i++) {
9603                 if (capability->fps_ranges_tbl[i].min_fps <
9604                         adjustedRange.min_fps) {
9605                     adjustedRange.min_fps =
9606                             capability->fps_ranges_tbl[i].min_fps;
9607                     adjustedRange.max_fps = adjustedRange.min_fps;
9608                 }
9609             }
9610             skipPattern = MAX_SKIP;
9611             adjustedRange.video_min_fps = adjustedRange.min_fps;
9612             adjustedRange.video_max_fps = adjustedRange.max_fps;
9613         }
9614         break;
9615     case QCAMERA_THERMAL_SHUTDOWN:
9616         {
9617             // send error notify
9618             LOGE("Received shutdown thermal level. Closing camera");
9619             sendEvtNotify(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0);
9620         }
9621         break;
9622     default:
9623         {
9624             LOGW("Invalid thermal level %d", level);
9625             return BAD_VALUE;
9626         }
9627         break;
9628     }
9629     if (level >= QCAMERA_THERMAL_NO_ADJUSTMENT && level <= QCAMERA_THERMAL_MAX_ADJUSTMENT) {
9630         if (bRecordingHint) {
9631             adjustedRange.min_fps = minFPS / 1000.0f;
9632             adjustedRange.max_fps = maxFPS / 1000.0f;
9633             adjustedRange.video_min_fps = minVideoFps / 1000.0f;
9634             adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
9635             skipPattern = NO_SKIP;
9636             LOGH("No FPS mitigation in camcorder mode");
9637         }
9638         LOGH("Thermal level %d, FPS [%3.2f,%3.2f, %3.2f,%3.2f], frameskip %d",
9639                   level, adjustedRange.min_fps, adjustedRange.max_fps,
9640                     adjustedRange.video_min_fps, adjustedRange.video_max_fps, skipPattern);
9641     }
9642 
9643     return NO_ERROR;
9644 }
9645 
9646 /*===========================================================================
9647  * FUNCTION   : recalcFPSRange
9648  *
9649  * DESCRIPTION: adjust the configured fps range regarding
9650  *              the last thermal level.
9651  *
9652  * PARAMETERS :
9653  *   @minFPS      : minimum configured fps range
9654  *   @maxFPS      : maximum configured fps range
9655  *   @minVideoFPS : minimum configured video fps
9656  *   @maxVideoFPS : maximum configured video fps
9657  *   @adjustedRange : target fps range
9658  *   @bRecordingHint : recording hint value
9659  *
9660  * RETURN     : int32_t type of status
9661  *              NO_ERROR  -- success
9662  *              none-zero failure code
9663  *==========================================================================*/
recalcFPSRange(int & minFPS,int & maxFPS,const float & minVideoFPS,const float & maxVideoFPS,cam_fps_range_t & adjustedRange,bool bRecordingHint)9664 int QCamera2HardwareInterface::recalcFPSRange(int &minFPS, int &maxFPS,
9665         const float &minVideoFPS, const float &maxVideoFPS,
9666         cam_fps_range_t &adjustedRange, bool bRecordingHint)
9667 {
9668     enum msm_vfe_frame_skip_pattern skipPattern;
9669     calcThermalLevel(mThermalLevel,
9670                      minFPS,
9671                      maxFPS,
9672                      minVideoFPS,
9673                      maxVideoFPS,
9674                      adjustedRange,
9675                      skipPattern,
9676                      bRecordingHint);
9677     return NO_ERROR;
9678 }
9679 
9680 /*===========================================================================
9681  * FUNCTION   : updateThermalLevel
9682  *
9683  * DESCRIPTION: update thermal level depending on thermal events
9684  *
9685  * PARAMETERS :
9686  *   @level   : thermal level
9687  *
9688  * RETURN     : int32_t type of status
9689  *              NO_ERROR  -- success
9690  *              none-zero failure code
9691  *==========================================================================*/
updateThermalLevel(void * thermal_level)9692 int QCamera2HardwareInterface::updateThermalLevel(void *thermal_level)
9693 {
9694     int ret = NO_ERROR;
9695     cam_fps_range_t adjustedRange;
9696     int minFPS, maxFPS;
9697     float minVideoFPS, maxVideoFPS;
9698     enum msm_vfe_frame_skip_pattern skipPattern;
9699     bool value;
9700     qcamera_thermal_level_enum_t level = *(qcamera_thermal_level_enum_t *)thermal_level;
9701 
9702 
9703     if (!mCameraOpened) {
9704         LOGH("Camera is not opened, no need to update camera parameters");
9705         return NO_ERROR;
9706     }
9707 
9708     mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
9709     qcamera_thermal_mode thermalMode = mParameters.getThermalMode();
9710     if (mParameters.isHfrMode()) {
9711         cam_fps_range_t hfrFpsRange;
9712         mParameters.getHfrFps(hfrFpsRange);
9713         minVideoFPS = hfrFpsRange.video_min_fps;
9714         maxVideoFPS = hfrFpsRange.video_max_fps;
9715     } else {
9716         minVideoFPS = minFPS;
9717         maxVideoFPS = maxFPS;
9718     }
9719 
9720     value = mParameters.getRecordingHintValue();
9721     calcThermalLevel(level, minFPS, maxFPS, minVideoFPS, maxVideoFPS,
9722             adjustedRange, skipPattern, value );
9723     mThermalLevel = level;
9724 
9725     if (thermalMode == QCAMERA_THERMAL_ADJUST_FPS)
9726         ret = mParameters.adjustPreviewFpsRange(&adjustedRange);
9727     else if (thermalMode == QCAMERA_THERMAL_ADJUST_FRAMESKIP)
9728         ret = mParameters.setFrameSkip(skipPattern);
9729     else
9730         LOGW("Incorrect thermal mode %d", thermalMode);
9731 
9732     return ret;
9733 
9734 }
9735 
9736 /*===========================================================================
9737  * FUNCTION   : updateParameters
9738  *
9739  * DESCRIPTION: update parameters
9740  *
9741  * PARAMETERS :
9742  *   @parms       : input parameters string
9743  *   @needRestart : output, flag to indicate if preview restart is needed
9744  *
9745  * RETURN     : int32_t type of status
9746  *              NO_ERROR  -- success
9747  *              none-zero failure code
9748  *==========================================================================*/
updateParameters(const char * parms,bool & needRestart)9749 int QCamera2HardwareInterface::updateParameters(const char *parms, bool &needRestart)
9750 {
9751     int rc = NO_ERROR;
9752 
9753     String8 str = String8(parms);
9754     rc =  mParameters.updateParameters(str, needRestart);
9755     setNeedRestart(needRestart);
9756 
9757     // update stream based parameter settings
9758     for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
9759         if (m_channels[i] != NULL) {
9760             m_channels[i]->UpdateStreamBasedParameters(mParameters);
9761         }
9762     }
9763 
9764     return rc;
9765 }
9766 
9767 /*===========================================================================
9768  * FUNCTION   : commitParameterChanges
9769  *
9770  * DESCRIPTION: commit parameter changes to the backend to take effect
9771  *
9772  * PARAMETERS : none
9773  *
9774  * RETURN     : int32_t type of status
9775  *              NO_ERROR  -- success
9776  *              none-zero failure code
9777  * NOTE       : This function must be called after updateParameters.
9778  *              Otherwise, no change will be passed to backend to take effect.
9779  *==========================================================================*/
commitParameterChanges()9780 int QCamera2HardwareInterface::commitParameterChanges()
9781 {
9782     int rc = NO_ERROR;
9783     rc = mParameters.commitParameters();
9784     if (rc == NO_ERROR) {
9785         // update number of snapshot based on committed parameters setting
9786         rc = mParameters.setNumOfSnapshot();
9787     }
9788 
9789     if (isDualCamera() &&
9790         mParameters.isZoomChanged()) {
9791         // If zoom changes, get the updated FOV-control result and if needed send the dual
9792         // camera parameters to backend
9793         processDualCamFovControl();
9794     }
9795     return rc;
9796 }
9797 
9798 /*===========================================================================
9799  * FUNCTION   : needDebugFps
9800  *
9801  * DESCRIPTION: if fps log info need to be printed out
9802  *
9803  * PARAMETERS : none
9804  *
9805  * RETURN     : true: need print out fps log
9806  *              false: no need to print out fps log
9807  *==========================================================================*/
needDebugFps()9808 bool QCamera2HardwareInterface::needDebugFps()
9809 {
9810     bool needFps = false;
9811     needFps = mParameters.isFpsDebugEnabled();
9812     return needFps;
9813 }
9814 
9815 /*===========================================================================
9816  * FUNCTION   : isCACEnabled
9817  *
9818  * DESCRIPTION: if CAC is enabled
9819  *
9820  * PARAMETERS : none
9821  *
9822  * RETURN     : true: needed
9823  *              false: no need
9824  *==========================================================================*/
isCACEnabled()9825 bool QCamera2HardwareInterface::isCACEnabled()
9826 {
9827     char prop[PROPERTY_VALUE_MAX];
9828     memset(prop, 0, sizeof(prop));
9829     property_get("persist.camera.feature.cac", prop, "0");
9830     int enableCAC = atoi(prop);
9831     return enableCAC == 1;
9832 }
9833 
9834 /*===========================================================================
9835  * FUNCTION   : is4k2kResolution
9836  *
9837  * DESCRIPTION: if resolution is 4k x 2k or true 4k x 2k
9838  *
9839  * PARAMETERS : none
9840  *
9841  * RETURN     : true: needed
9842  *              false: no need
9843  *==========================================================================*/
is4k2kResolution(cam_dimension_t * resolution)9844 bool QCamera2HardwareInterface::is4k2kResolution(cam_dimension_t* resolution)
9845 {
9846    bool enabled = false;
9847    if ((resolution->width == 4096 && resolution->height == 2160) ||
9848        (resolution->width == 3840 && resolution->height == 2160) ) {
9849       enabled = true;
9850    }
9851    return enabled;
9852 }
9853 
9854 /*===========================================================================
9855  * FUNCTION   : isPreviewRestartEnabled
9856  *
9857  * DESCRIPTION: Check whether preview should be restarted automatically
9858  *              during image capture.
9859  *
9860  * PARAMETERS : none
9861  *
9862  * RETURN     : true: needed
9863  *              false: no need
9864  *==========================================================================*/
isPreviewRestartEnabled()9865 bool QCamera2HardwareInterface::isPreviewRestartEnabled()
9866 {
9867     char prop[PROPERTY_VALUE_MAX];
9868     memset(prop, 0, sizeof(prop));
9869     property_get("persist.camera.feature.restart", prop, "0");
9870     int earlyRestart = atoi(prop);
9871     return earlyRestart == 1;
9872 }
9873 
9874 /*===========================================================================
9875  * FUNCTION   : needReprocess
9876  *
9877  * DESCRIPTION: if reprocess is needed
9878  *
9879  * PARAMETERS : none
9880  *
9881  * RETURN     : true: needed
9882  *              false: no need
9883  *==========================================================================*/
needReprocess()9884 bool QCamera2HardwareInterface::needReprocess()
9885 {
9886     bool needReprocess = false;
9887 
9888     if (!mParameters.isJpegPictureFormat() &&
9889         !mParameters.isNV21PictureFormat()) {
9890         // RAW image, no need to reprocess
9891         return false;
9892     }
9893 
9894     //Disable reprocess for small jpeg size or 4K liveshot case but enable if lowpower mode
9895     if ((mParameters.is4k2kVideoResolution() && mParameters.getRecordingHintValue()
9896             && !isLowPowerMode()) || mParameters.isSmallJpegSizeEnabled()) {
9897         return false;
9898     }
9899 
9900     // pp feature config
9901     cam_pp_feature_config_t pp_config;
9902     memset(&pp_config, 0, sizeof(cam_pp_feature_config_t));
9903 
9904     //Decide whether to do reprocess or not based on
9905     //ppconfig obtained in the first pass.
9906     getPPConfig(pp_config);
9907 
9908     if (pp_config.feature_mask > 0) {
9909         needReprocess = true;
9910     }
9911 
9912     LOGH("needReprocess %s", needReprocess ? "true" : "false");
9913     return needReprocess;
9914 }
9915 
9916 
9917 /*===========================================================================
9918  * FUNCTION   : needRotationReprocess
9919  *
9920  * DESCRIPTION: if rotation needs to be done by reprocess in pp
9921  *
9922  * PARAMETERS : none
9923  *
9924  * RETURN     : true: needed
9925  *              false: no need
9926  *==========================================================================*/
needRotationReprocess()9927 bool QCamera2HardwareInterface::needRotationReprocess()
9928 {
9929     if (!mParameters.isJpegPictureFormat() &&
9930         !mParameters.isNV21PictureFormat()) {
9931         // RAW image, no need to reprocess
9932         return false;
9933     }
9934 
9935     //Disable reprocess for 4K liveshot case
9936     if ((mParameters.is4k2kVideoResolution() && mParameters.getRecordingHintValue()
9937             && !isLowPowerMode()) || mParameters.isSmallJpegSizeEnabled()) {
9938         //Disable reprocess for 4K liveshot case or small jpeg size
9939          return false;
9940     }
9941 
9942     if ((gCamCapability[mCameraId]->qcom_supported_feature_mask &
9943             CAM_QCOM_FEATURE_ROTATION) > 0 &&
9944             (mParameters.getJpegRotation() > 0)) {
9945         // current rotation is not zero, and pp has the capability to process rotation
9946         LOGH("need to do reprocess for rotation=%d",
9947                  mParameters.getJpegRotation());
9948         return true;
9949     }
9950 
9951     return false;
9952 }
9953 
9954 /*===========================================================================
9955  * FUNCTION   : getThumbnailSize
9956  *
9957  * DESCRIPTION: get user set thumbnail size
9958  *
9959  * PARAMETERS :
9960  *   @dim     : output of thumbnail dimension
9961  *
9962  * RETURN     : none
9963  *==========================================================================*/
getThumbnailSize(cam_dimension_t & dim)9964 void QCamera2HardwareInterface::getThumbnailSize(cam_dimension_t &dim)
9965 {
9966     mParameters.getThumbnailSize(&dim.width, &dim.height);
9967 }
9968 
9969 /*===========================================================================
9970  * FUNCTION   : getJpegQuality
9971  *
9972  * DESCRIPTION: get user set jpeg quality
9973  *
9974  * PARAMETERS : none
9975  *
9976  * RETURN     : jpeg quality setting
9977  *==========================================================================*/
getJpegQuality()9978 uint32_t QCamera2HardwareInterface::getJpegQuality()
9979 {
9980     uint32_t quality = 0;
9981     quality =  mParameters.getJpegQuality();
9982     return quality;
9983 }
9984 
9985 /*===========================================================================
9986  * FUNCTION   : getExifData
9987  *
9988  * DESCRIPTION: get exif data to be passed into jpeg encoding
9989  *
9990  * PARAMETERS : none
9991  *
9992  * RETURN     : exif data from user setting and GPS
9993  *==========================================================================*/
getExifData()9994 QCameraExif *QCamera2HardwareInterface::getExifData()
9995 {
9996     QCameraExif *exif = new QCameraExif();
9997     if (exif == NULL) {
9998         LOGE("No memory for QCameraExif");
9999         return NULL;
10000     }
10001 
10002     int32_t rc = NO_ERROR;
10003 
10004     // add exif entries
10005     String8 dateTime, subSecTime;
10006     rc = mParameters.getExifDateTime(dateTime, subSecTime);
10007     if(rc == NO_ERROR) {
10008         exif->addEntry(EXIFTAGID_DATE_TIME, EXIF_ASCII,
10009                 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string());
10010         exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, EXIF_ASCII,
10011                 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string());
10012         exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_DIGITIZED, EXIF_ASCII,
10013                 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string());
10014         exif->addEntry(EXIFTAGID_SUBSEC_TIME, EXIF_ASCII,
10015                 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string());
10016         exif->addEntry(EXIFTAGID_SUBSEC_TIME_ORIGINAL, EXIF_ASCII,
10017                 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string());
10018         exif->addEntry(EXIFTAGID_SUBSEC_TIME_DIGITIZED, EXIF_ASCII,
10019                 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string());
10020     } else {
10021         LOGW("getExifDateTime failed");
10022     }
10023 
10024     rat_t focalLength;
10025     rc = mParameters.getExifFocalLength(&focalLength);
10026     if (rc == NO_ERROR) {
10027         exif->addEntry(EXIFTAGID_FOCAL_LENGTH,
10028                        EXIF_RATIONAL,
10029                        1,
10030                        (void *)&(focalLength));
10031     } else {
10032         LOGW("getExifFocalLength failed");
10033     }
10034 
10035     uint16_t isoSpeed = mParameters.getExifIsoSpeed();
10036     if (getSensorType() != CAM_SENSOR_YUV) {
10037         exif->addEntry(EXIFTAGID_ISO_SPEED_RATING,
10038                        EXIF_SHORT,
10039                        1,
10040                        (void *)&(isoSpeed));
10041     }
10042 
10043     char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE];
10044     uint32_t count = 0;
10045 
10046     /*gps data might not be available */
10047     rc = mParameters.getExifGpsProcessingMethod(gpsProcessingMethod, count);
10048     if(rc == NO_ERROR) {
10049         exif->addEntry(EXIFTAGID_GPS_PROCESSINGMETHOD,
10050                        EXIF_ASCII,
10051                        count,
10052                        (void *)gpsProcessingMethod);
10053     } else {
10054         LOGW("getExifGpsProcessingMethod failed");
10055     }
10056 
10057     rat_t latitude[3];
10058     char latRef[2];
10059     rc = mParameters.getExifLatitude(latitude, latRef);
10060     if(rc == NO_ERROR) {
10061         exif->addEntry(EXIFTAGID_GPS_LATITUDE,
10062                        EXIF_RATIONAL,
10063                        3,
10064                        (void *)latitude);
10065         exif->addEntry(EXIFTAGID_GPS_LATITUDE_REF,
10066                        EXIF_ASCII,
10067                        2,
10068                        (void *)latRef);
10069     } else {
10070         LOGW("getExifLatitude failed");
10071     }
10072 
10073     rat_t longitude[3];
10074     char lonRef[2];
10075     rc = mParameters.getExifLongitude(longitude, lonRef);
10076     if(rc == NO_ERROR) {
10077         exif->addEntry(EXIFTAGID_GPS_LONGITUDE,
10078                        EXIF_RATIONAL,
10079                        3,
10080                        (void *)longitude);
10081 
10082         exif->addEntry(EXIFTAGID_GPS_LONGITUDE_REF,
10083                        EXIF_ASCII,
10084                        2,
10085                        (void *)lonRef);
10086     } else {
10087         LOGW("getExifLongitude failed");
10088     }
10089 
10090     rat_t altitude;
10091     char altRef;
10092     rc = mParameters.getExifAltitude(&altitude, &altRef);
10093     if(rc == NO_ERROR) {
10094         exif->addEntry(EXIFTAGID_GPS_ALTITUDE,
10095                        EXIF_RATIONAL,
10096                        1,
10097                        (void *)&(altitude));
10098 
10099         exif->addEntry(EXIFTAGID_GPS_ALTITUDE_REF,
10100                        EXIF_BYTE,
10101                        1,
10102                        (void *)&altRef);
10103     } else {
10104         LOGW("getExifAltitude failed");
10105     }
10106 
10107     char gpsDateStamp[20];
10108     rat_t gpsTimeStamp[3];
10109     rc = mParameters.getExifGpsDateTimeStamp(gpsDateStamp, 20, gpsTimeStamp);
10110     if(rc == NO_ERROR) {
10111         exif->addEntry(EXIFTAGID_GPS_DATESTAMP,
10112                        EXIF_ASCII,
10113                        (uint32_t)(strlen(gpsDateStamp) + 1),
10114                        (void *)gpsDateStamp);
10115 
10116         exif->addEntry(EXIFTAGID_GPS_TIMESTAMP,
10117                        EXIF_RATIONAL,
10118                        3,
10119                        (void *)gpsTimeStamp);
10120     } else {
10121         LOGW("getExifGpsDataTimeStamp failed");
10122     }
10123 
10124 #ifdef ENABLE_MODEL_INFO_EXIF
10125 
10126     char value[PROPERTY_VALUE_MAX];
10127     if (property_get("persist.sys.exif.make", value, "") > 0 ||
10128             property_get("ro.product.manufacturer", value, "QCOM-AA") > 0) {
10129         exif->addEntry(EXIFTAGID_MAKE,
10130                 EXIF_ASCII, strlen(value) + 1, (void *)value);
10131     } else {
10132         LOGW("getExifMaker failed");
10133     }
10134 
10135     if (property_get("persist.sys.exif.model", value, "") > 0 ||
10136             property_get("ro.product.model", value, "QCAM-AA") > 0) {
10137         exif->addEntry(EXIFTAGID_MODEL,
10138                 EXIF_ASCII, strlen(value) + 1, (void *)value);
10139     } else {
10140         LOGW("getExifModel failed");
10141     }
10142 
10143     if (property_get("ro.build.description", value, "QCAM-AA") > 0) {
10144         exif->addEntry(EXIFTAGID_SOFTWARE, EXIF_ASCII,
10145                 (uint32_t)(strlen(value) + 1), (void *)value);
10146     } else {
10147         LOGW("getExifSoftware failed");
10148     }
10149 
10150 #endif
10151 
10152     if (mParameters.useJpegExifRotation()) {
10153         int16_t orientation;
10154         switch (mParameters.getJpegExifRotation()) {
10155         case 0:
10156             orientation = 1;
10157             break;
10158         case 90:
10159             orientation = 6;
10160             break;
10161         case 180:
10162             orientation = 3;
10163             break;
10164         case 270:
10165             orientation = 8;
10166             break;
10167         default:
10168             orientation = 1;
10169             break;
10170         }
10171         exif->addEntry(EXIFTAGID_ORIENTATION,
10172                 EXIF_SHORT,
10173                 1,
10174                 (void *)&orientation);
10175         exif->addEntry(EXIFTAGID_TN_ORIENTATION,
10176                 EXIF_SHORT,
10177                 1,
10178                 (void *)&orientation);
10179     }
10180 
10181     return exif;
10182 }
10183 
10184 /*===========================================================================
10185  * FUNCTION   : setHistogram
10186  *
10187  * DESCRIPTION: set if histogram should be enabled
10188  *
10189  * PARAMETERS :
10190  *   @histogram_en : bool flag if histogram should be enabled
10191  *
10192  * RETURN     : int32_t type of status
10193  *              NO_ERROR  -- success
10194  *              none-zero failure code
10195  *==========================================================================*/
setHistogram(bool histogram_en)10196 int32_t QCamera2HardwareInterface::setHistogram(bool histogram_en)
10197 {
10198     return mParameters.setHistogram(histogram_en);
10199 }
10200 
10201 /*===========================================================================
10202  * FUNCTION   : setFaceDetection
10203  *
10204  * DESCRIPTION: set if face detection should be enabled
10205  *
10206  * PARAMETERS :
10207  *   @enabled : bool flag if face detection should be enabled
10208  *
10209  * RETURN     : int32_t type of status
10210  *              NO_ERROR  -- success
10211  *              none-zero failure code
10212  *==========================================================================*/
setFaceDetection(bool enabled)10213 int32_t QCamera2HardwareInterface::setFaceDetection(bool enabled)
10214 {
10215     return mParameters.setFaceDetection(enabled, true);
10216 }
10217 
10218 /*===========================================================================
10219  * FUNCTION   : isCaptureShutterEnabled
10220  *
10221  * DESCRIPTION: Check whether shutter should be triggered immediately after
10222  *              capture
10223  *
10224  * PARAMETERS :
10225  *
10226  * RETURN     : true - regular capture
10227  *              false - other type of capture
10228  *==========================================================================*/
isCaptureShutterEnabled()10229 bool QCamera2HardwareInterface::isCaptureShutterEnabled()
10230 {
10231     char prop[PROPERTY_VALUE_MAX];
10232     memset(prop, 0, sizeof(prop));
10233     property_get("persist.camera.feature.shutter", prop, "0");
10234     int enableShutter = atoi(prop);
10235     return enableShutter == 1;
10236 }
10237 
10238 /*===========================================================================
10239  * FUNCTION   : needProcessPreviewFrame
10240  *
10241  * DESCRIPTION: returns whether preview frame need to be displayed
10242  *
10243  * PARAMETERS :
10244  *   @frameID : frameID of frame to be processed
10245  *
10246  * RETURN     : int32_t type of status
10247  *              NO_ERROR  -- success
10248  *              none-zero failure code
10249  *==========================================================================*/
needProcessPreviewFrame(uint32_t frameID)10250 bool QCamera2HardwareInterface::needProcessPreviewFrame(uint32_t frameID)
10251 {
10252     return (((m_stateMachine.isPreviewRunning()) &&
10253             (!isDisplayFrameToSkip(frameID)) &&
10254             (!mParameters.isInstantAECEnabled())) ||
10255             (isPreviewRestartEnabled()));
10256 }
10257 
10258 /*===========================================================================
10259  * FUNCTION   : needSendPreviewCallback
10260  *
10261  * DESCRIPTION: returns whether preview frame need to callback to APP
10262  *
10263  * PARAMETERS :
10264  *
10265  * RETURN     : true - need preview frame callbck
10266  *              false - not send preview frame callback
10267  *==========================================================================*/
needSendPreviewCallback()10268 bool QCamera2HardwareInterface::needSendPreviewCallback()
10269 {
10270     return m_stateMachine.isPreviewRunning()
10271             && (mDataCb != NULL)
10272             && (msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_FRAME) > 0)
10273             && m_stateMachine.isPreviewCallbackNeeded();
10274 };
10275 
10276 /*===========================================================================
10277  * FUNCTION   : setDisplaySkip
10278  *
10279  * DESCRIPTION: set range of frames to skip for preview
10280  *
10281  * PARAMETERS :
10282  *   @enabled : TRUE to start skipping frame to display
10283                 FALSE to stop skipping frame to display
10284  *   @skipCnt : Number of frame to skip. 0 by default
10285  *
10286  * RETURN     : None
10287  *==========================================================================*/
setDisplaySkip(bool enabled,uint8_t skipCnt)10288 void QCamera2HardwareInterface::setDisplaySkip(bool enabled, uint8_t skipCnt)
10289 {
10290     pthread_mutex_lock(&mGrallocLock);
10291     if (enabled) {
10292         setDisplayFrameSkip();
10293         setDisplayFrameSkip(mLastPreviewFrameID + skipCnt + 1);
10294     } else {
10295         setDisplayFrameSkip(mFrameSkipStart, (mLastPreviewFrameID + skipCnt + 1));
10296     }
10297     pthread_mutex_unlock(&mGrallocLock);
10298 }
10299 
10300 /*===========================================================================
10301  * FUNCTION   : setDisplayFrameSkip
10302  *
10303  * DESCRIPTION: set range of frames to skip for preview
10304  *
10305  * PARAMETERS :
10306  *   @start   : frameId to start skip
10307  *   @end     : frameId to stop skip
10308  *
10309  * RETURN     : None
10310  *==========================================================================*/
setDisplayFrameSkip(uint32_t start,uint32_t end)10311 void QCamera2HardwareInterface::setDisplayFrameSkip(uint32_t start,
10312         uint32_t end)
10313 {
10314     if (start == 0) {
10315         mFrameSkipStart = 0;
10316         mFrameSkipEnd = 0;
10317         return;
10318     }
10319     if ((mFrameSkipStart == 0) || (mFrameSkipStart > start)) {
10320         mFrameSkipStart = start;
10321     }
10322     if ((end == 0) || (end > mFrameSkipEnd)) {
10323         mFrameSkipEnd = end;
10324     }
10325 }
10326 
10327 /*===========================================================================
10328  * FUNCTION   : isDisplayFrameToSkip
10329  *
10330  * DESCRIPTION: function to determin if input frame falls under skip range
10331  *
10332  * PARAMETERS :
10333  *   @frameId : frameId to verify
10334  *
10335  * RETURN     : true : need to skip
10336  *              false: no need to skip
10337  *==========================================================================*/
isDisplayFrameToSkip(uint32_t frameId)10338 bool QCamera2HardwareInterface::isDisplayFrameToSkip(uint32_t frameId)
10339 {
10340     return ((mFrameSkipStart != 0) && (frameId >= mFrameSkipStart) &&
10341             (frameId <= mFrameSkipEnd || mFrameSkipEnd == 0)) ? TRUE : FALSE;
10342 }
10343 
10344 /*===========================================================================
10345  * FUNCTION   : getSnapshotHandle
10346  *
10347  * DESCRIPTION: Get the camera handle for snapshot based on the bundlesnapshot
10348  *              flag and active camera state
10349  *
10350  * PARAMETERS : None
10351  *
10352  * RETURN     : camera handle for snapshot
10353  *
10354  *==========================================================================*/
getSnapshotHandle()10355 uint32_t QCamera2HardwareInterface::getSnapshotHandle()
10356 {
10357     uint32_t snapshotHandle = 0;
10358 
10359     if ((mActiveCameras == MM_CAMERA_DUAL_CAM) && mBundledSnapshot) {
10360         snapshotHandle = mCameraHandle->camera_handle;
10361     } else {
10362         snapshotHandle = (mMasterCamera == MM_CAMERA_TYPE_MAIN) ?
10363                 get_main_camera_handle(mCameraHandle->camera_handle) :
10364                 get_aux_camera_handle(mCameraHandle->camera_handle);
10365     }
10366 
10367     return snapshotHandle;
10368 }
10369 
10370 /*===========================================================================
10371  * FUNCTION   : prepareHardwareForSnapshot
10372  *
10373  * DESCRIPTION: prepare hardware for snapshot, such as LED
10374  *
10375  * PARAMETERS :
10376  *   @afNeeded: flag indicating if Auto Focus needs to be done during preparation
10377  *
10378  * RETURN     : int32_t type of status
10379  *              NO_ERROR  -- success
10380  *              none-zero failure code
10381  *==========================================================================*/
prepareHardwareForSnapshot(int32_t afNeeded)10382 int32_t QCamera2HardwareInterface::prepareHardwareForSnapshot(int32_t afNeeded)
10383 {
10384     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PREPARE_HW_FOR_SNAPSHOT);
10385     LOGI("[KPI Perf]: Send PREPARE SANSPHOT event");
10386     return mCameraHandle->ops->prepare_snapshot(getSnapshotHandle(),
10387                                                 afNeeded);
10388 }
10389 
10390 /*===========================================================================
10391  * FUNCTION   : needFDMetadata
10392  *
10393  * DESCRIPTION: check whether we need process Face Detection metadata in this chanel
10394  *
10395  * PARAMETERS :
10396  *   @channel_type: channel type
10397  *
10398   * RETURN     : true: needed
10399  *              false: no need
10400  *==========================================================================*/
needFDMetadata(qcamera_ch_type_enum_t channel_type)10401 bool QCamera2HardwareInterface::needFDMetadata(qcamera_ch_type_enum_t channel_type)
10402 {
10403     //Note: Currently we only process ZSL channel
10404     bool value = false;
10405     if(channel_type == QCAMERA_CH_TYPE_ZSL){
10406         //check if FD requirement is enabled
10407         if(mParameters.isSnapshotFDNeeded() &&
10408            mParameters.isFaceDetectionEnabled()){
10409             value = true;
10410             LOGH("Face Detection metadata is required in ZSL mode.");
10411         }
10412     }
10413 
10414     return value;
10415 }
10416 
10417 /*===========================================================================
10418  * FUNCTION   : deferredWorkRoutine
10419  *
10420  * DESCRIPTION: data process routine that executes deferred tasks
10421  *
10422  * PARAMETERS :
10423  *   @data    : user data ptr (QCamera2HardwareInterface)
10424  *
10425  * RETURN     : None
10426  *==========================================================================*/
deferredWorkRoutine(void * obj)10427 void *QCamera2HardwareInterface::deferredWorkRoutine(void *obj)
10428 {
10429     int running = 1;
10430     int ret;
10431     uint8_t is_active = FALSE;
10432     int32_t job_status = 0;
10433 
10434     QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)obj;
10435     QCameraCmdThread *cmdThread = &pme->mDeferredWorkThread;
10436     cmdThread->setName("CAM_defrdWrk");
10437 
10438     do {
10439         do {
10440             ret = cam_sem_wait(&cmdThread->cmd_sem);
10441             if (ret != 0 && errno != EINVAL) {
10442                 LOGE("cam_sem_wait error (%s)",
10443                          strerror(errno));
10444                 return NULL;
10445             }
10446         } while (ret != 0);
10447 
10448         // we got notified about new cmd avail in cmd queue
10449         camera_cmd_type_t cmd = cmdThread->getCmd();
10450         LOGD("cmd: %d", cmd);
10451         switch (cmd) {
10452         case CAMERA_CMD_TYPE_START_DATA_PROC:
10453             LOGH("start data proc");
10454             is_active = TRUE;
10455             break;
10456         case CAMERA_CMD_TYPE_STOP_DATA_PROC:
10457             LOGH("stop data proc");
10458             is_active = FALSE;
10459             // signal cmd is completed
10460             cam_sem_post(&cmdThread->sync_sem);
10461             break;
10462         case CAMERA_CMD_TYPE_DO_NEXT_JOB:
10463             {
10464                 DefWork *dw =
10465                     reinterpret_cast<DefWork *>(pme->mCmdQueue.dequeue());
10466 
10467                 if ( NULL == dw ) {
10468                     LOGE("Invalid deferred work");
10469                     break;
10470                 }
10471 
10472                 switch( dw->cmd ) {
10473                 case CMD_DEF_ALLOCATE_BUFF:
10474                     {
10475                         QCameraChannel * pChannel = dw->args.allocArgs.ch;
10476 
10477                         if ( NULL == pChannel ) {
10478                             LOGE("Invalid deferred work channel");
10479                             job_status = BAD_VALUE;
10480                             break;
10481                         }
10482 
10483                         cam_stream_type_t streamType = dw->args.allocArgs.type;
10484                         LOGH("Deferred buffer allocation started for stream type: %d",
10485                                  streamType);
10486 
10487                         uint32_t iNumOfStreams = pChannel->getNumOfStreams();
10488                         QCameraStream *pStream = NULL;
10489                         for ( uint32_t i = 0; i < iNumOfStreams; ++i) {
10490                             pStream = pChannel->getStreamByIndex(i);
10491 
10492                             if ( NULL == pStream ) {
10493                                 job_status = BAD_VALUE;
10494                                 break;
10495                             }
10496 
10497                             if ( pStream->isTypeOf(streamType)) {
10498                                 if ( pStream->allocateBuffers() ) {
10499                                     LOGE("Error allocating buffers !!!");
10500                                     job_status =  NO_MEMORY;
10501                                     pme->sendEvtNotify(CAMERA_MSG_ERROR,
10502                                             CAMERA_ERROR_UNKNOWN, 0);
10503                                 }
10504                                 break;
10505                             }
10506                         }
10507                     }
10508                     break;
10509                 case CMD_DEF_PPROC_START:
10510                     {
10511                         int32_t ret = pme->getDefJobStatus(pme->mInitPProcJob);
10512                         if (ret != NO_ERROR) {
10513                             job_status = ret;
10514                             LOGE("PPROC Start failed");
10515                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
10516                                     CAMERA_ERROR_UNKNOWN, 0);
10517                             break;
10518                         }
10519                         QCameraChannel * pChannel = dw->args.pprocArgs;
10520                         assert(pChannel);
10521 
10522                         if (pme->m_postprocessor.start(pChannel) != NO_ERROR) {
10523                             LOGE("cannot start postprocessor");
10524                             job_status = BAD_VALUE;
10525                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
10526                                     CAMERA_ERROR_UNKNOWN, 0);
10527                         }
10528                     }
10529                     break;
10530                 case CMD_DEF_METADATA_ALLOC:
10531                     {
10532                         int32_t ret = pme->getDefJobStatus(pme->mParamAllocJob);
10533                         if (ret != NO_ERROR) {
10534                             job_status = ret;
10535                             LOGE("Metadata alloc failed");
10536                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
10537                                     CAMERA_ERROR_UNKNOWN, 0);
10538                             break;
10539                         }
10540                         pme->mMetadataMem = new QCameraMetadataStreamMemory(
10541                                 QCAMERA_ION_USE_CACHE);
10542 
10543                         if (pme->mMetadataMem == NULL) {
10544                             LOGE("Unable to allocate metadata buffers");
10545                             job_status = BAD_VALUE;
10546                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
10547                                     CAMERA_ERROR_UNKNOWN, 0);
10548                         } else {
10549                             int32_t rc = pme->mMetadataMem->allocate(
10550                                     dw->args.metadataAllocArgs.bufferCnt,
10551                                     dw->args.metadataAllocArgs.size);
10552                             if (rc < 0) {
10553                                 delete pme->mMetadataMem;
10554                                 pme->mMetadataMem = NULL;
10555                             }
10556                         }
10557                      }
10558                      break;
10559                 case CMD_DEF_CREATE_JPEG_SESSION:
10560                     {
10561                         QCameraChannel * pChannel = dw->args.pprocArgs;
10562                         assert(pChannel);
10563 
10564                         int32_t ret = pme->getDefJobStatus(pme->mReprocJob);
10565                         if (ret != NO_ERROR) {
10566                             job_status = ret;
10567                             LOGE("Jpeg create failed");
10568                             break;
10569                         }
10570 
10571                         if (pme->m_postprocessor.createJpegSession(pChannel)
10572                             != NO_ERROR) {
10573                             LOGE("cannot create JPEG session");
10574                             job_status = UNKNOWN_ERROR;
10575                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
10576                                     CAMERA_ERROR_UNKNOWN, 0);
10577                         }
10578                     }
10579                     break;
10580                 case CMD_DEF_PPROC_INIT:
10581                     {
10582                         int32_t rc = NO_ERROR;
10583 
10584                         jpeg_encode_callback_t jpegEvtHandle =
10585                                 dw->args.pprocInitArgs.jpeg_cb;
10586                         void* user_data = dw->args.pprocInitArgs.user_data;
10587                         QCameraPostProcessor *postProcessor =
10588                                 &(pme->m_postprocessor);
10589                         uint32_t cameraId = pme->mCameraId;
10590                         cam_capability_t *capability =
10591                                 gCamCapability[cameraId];
10592                         cam_padding_info_t padding_info;
10593                         cam_padding_info_t& cam_capability_padding_info =
10594                                 capability->padding_info;
10595 
10596                         if(!pme->mJpegClientHandle) {
10597                             rc = pme->initJpegHandle();
10598                             if (rc != NO_ERROR) {
10599                                 LOGE("Error!! creating JPEG handle failed");
10600                                 job_status = UNKNOWN_ERROR;
10601                                 pme->sendEvtNotify(CAMERA_MSG_ERROR,
10602                                         CAMERA_ERROR_UNKNOWN, 0);
10603                                 break;
10604                             }
10605                         }
10606                         LOGH("mJpegClientHandle : %d", pme->mJpegClientHandle);
10607 
10608                         rc = postProcessor->setJpegHandle(&pme->mJpegHandle,
10609                                 &pme->mJpegMpoHandle,
10610                                 pme->mJpegClientHandle);
10611                         if (rc != 0) {
10612                             LOGE("Error!! set JPEG handle failed");
10613                             job_status = UNKNOWN_ERROR;
10614                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
10615                                     CAMERA_ERROR_UNKNOWN, 0);
10616                             break;
10617                         }
10618 
10619                         /* get max pic size for jpeg work buf calculation*/
10620                         rc = postProcessor->init(jpegEvtHandle, user_data);
10621 
10622                         if (rc != NO_ERROR) {
10623                             LOGE("cannot init postprocessor");
10624                             job_status = UNKNOWN_ERROR;
10625                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
10626                                     CAMERA_ERROR_UNKNOWN, 0);
10627                             break;
10628                         }
10629 
10630                         // update padding info from jpeg
10631                         postProcessor->getJpegPaddingReq(padding_info);
10632                         if (cam_capability_padding_info.width_padding <
10633                                 padding_info.width_padding) {
10634                             cam_capability_padding_info.width_padding =
10635                                     padding_info.width_padding;
10636                         }
10637                         if (cam_capability_padding_info.height_padding <
10638                                 padding_info.height_padding) {
10639                             cam_capability_padding_info.height_padding =
10640                                     padding_info.height_padding;
10641                         }
10642                         if (cam_capability_padding_info.plane_padding !=
10643                                 padding_info.plane_padding) {
10644                             cam_capability_padding_info.plane_padding =
10645                                     mm_stream_calc_lcm(
10646                                     cam_capability_padding_info.plane_padding,
10647                                     padding_info.plane_padding);
10648                         }
10649                         if (cam_capability_padding_info.offset_info.offset_x
10650                                 != padding_info.offset_info.offset_x) {
10651                             cam_capability_padding_info.offset_info.offset_x =
10652                                     mm_stream_calc_lcm (
10653                                     cam_capability_padding_info.offset_info.offset_x,
10654                                     padding_info.offset_info.offset_x);
10655                         }
10656                         if (cam_capability_padding_info.offset_info.offset_y
10657                                 != padding_info.offset_info.offset_y) {
10658                             cam_capability_padding_info.offset_info.offset_y =
10659                             mm_stream_calc_lcm (
10660                                     cam_capability_padding_info.offset_info.offset_y,
10661                                     padding_info.offset_info.offset_y);
10662                         }
10663                     }
10664                     break;
10665                 case CMD_DEF_PARAM_ALLOC:
10666                     {
10667                         int32_t rc = NO_ERROR;
10668                         if (pme->isDualCamera()) {
10669                             rc = pme->mParameters.allocate(MM_CAMERA_MAX_CAM_CNT);
10670                         } else {
10671                             rc = pme->mParameters.allocate();
10672                         }
10673                         // notify routine would not be initialized by this time.
10674                         // So, just update error job status
10675                         if (rc != NO_ERROR) {
10676                             job_status = rc;
10677                             LOGE("Param allocation failed");
10678                             break;
10679                         }
10680                     }
10681                     break;
10682                 case CMD_DEF_PARAM_INIT:
10683                     {
10684                         int32_t rc = pme->getDefJobStatus(pme->mParamAllocJob);
10685                         if (rc != NO_ERROR) {
10686                             job_status = rc;
10687                             LOGE("Param init failed");
10688                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
10689                                     CAMERA_ERROR_UNKNOWN, 0);
10690                             break;
10691                         }
10692 
10693                         uint32_t camId = pme->mCameraId;
10694                         cam_capability_t * cap = gCamCapability[camId];
10695 
10696                         if (pme->mCameraHandle == NULL) {
10697                             LOGE("Camera handle is null");
10698                             job_status = BAD_VALUE;
10699                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
10700                                     CAMERA_ERROR_UNKNOWN, 0);
10701                             break;
10702                         }
10703 
10704                         // Now PostProc need calibration data as initialization
10705                         // time for jpeg_open and calibration data is a
10706                         // get param for now, so params needs to be initialized
10707                         // before postproc init
10708                         rc = pme->mParameters.init(cap,
10709                                 pme->mCameraHandle,
10710                                 pme, pme->m_pFovControl);
10711                         if (rc != 0) {
10712                             job_status = UNKNOWN_ERROR;
10713                             LOGE("Parameter Initialization failed");
10714                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
10715                                     CAMERA_ERROR_UNKNOWN, 0);
10716                             break;
10717                         }
10718 
10719                         // Get related cam calibration only in
10720                         // dual camera mode
10721                         if ((pme->getRelatedCamSyncInfo()->sync_control ==
10722                                 CAM_SYNC_RELATED_SENSORS_ON) || pme->isDualCamera()){
10723                             rc = pme->mParameters.getRelatedCamCalibration(
10724                                 &(pme->mJpegMetadata.otp_calibration_data));
10725                             LOGD("Dumping Calibration Data Version Id %f rc %d",
10726                                     pme->mJpegMetadata.otp_calibration_data.calibration_format_version,
10727                                     rc);
10728                             if (rc != 0) {
10729                                 job_status = UNKNOWN_ERROR;
10730                                 LOGE("getRelatedCamCalibration failed");
10731                                 pme->sendEvtNotify(CAMERA_MSG_ERROR,
10732                                         CAMERA_ERROR_UNKNOWN, 0);
10733                                 break;
10734                             }
10735                             pme->m_bRelCamCalibValid = true;
10736                         }
10737 
10738                         pme->mJpegMetadata.sensor_mount_angle =
10739                             cap->sensor_mount_angle;
10740                         pme->mJpegMetadata.default_sensor_flip = FLIP_NONE;
10741 
10742                         pme->mParameters.setMinPpMask(
10743                             cap->qcom_supported_feature_mask);
10744                         pme->mExifParams.debug_params =
10745                                 (mm_jpeg_debug_exif_params_t *)
10746                                 malloc(sizeof(mm_jpeg_debug_exif_params_t));
10747                         if (!pme->mExifParams.debug_params) {
10748                             LOGE("Out of Memory. Allocation failed for "
10749                                     "3A debug exif params");
10750                             job_status = NO_MEMORY;
10751                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
10752                                     CAMERA_ERROR_UNKNOWN, 0);
10753                             break;
10754                         }
10755                         memset(pme->mExifParams.debug_params, 0,
10756                                 sizeof(mm_jpeg_debug_exif_params_t));
10757                     }
10758                     break;
10759                 case CMD_DEF_GENERIC:
10760                     {
10761                         BackgroundTask *bgTask = dw->args.genericArgs;
10762                         job_status = bgTask->bgFunction(bgTask->bgArgs);
10763                     }
10764                     break;
10765                 default:
10766                     LOGE("Incorrect command : %d", dw->cmd);
10767                 }
10768 
10769                 pme->dequeueDeferredWork(dw, job_status);
10770             }
10771             break;
10772         case CAMERA_CMD_TYPE_EXIT:
10773             running = 0;
10774             break;
10775         default:
10776             break;
10777         }
10778     } while (running);
10779 
10780     return NULL;
10781 }
10782 
10783 /*===========================================================================
10784  * FUNCTION   : queueDeferredWork
10785  *
10786  * DESCRIPTION: function which queues deferred tasks
10787  *
10788  * PARAMETERS :
10789  *   @cmd     : deferred task
10790  *   @args    : deferred task arguments
10791  *
10792  * RETURN     : job id of deferred job
10793  *            : 0 in case of error
10794  *==========================================================================*/
queueDeferredWork(DeferredWorkCmd cmd,DeferWorkArgs args)10795 uint32_t QCamera2HardwareInterface::queueDeferredWork(DeferredWorkCmd cmd,
10796                                                       DeferWorkArgs args)
10797 {
10798     Mutex::Autolock l(mDefLock);
10799     for (int32_t i = 0; i < MAX_ONGOING_JOBS; ++i) {
10800         if (mDefOngoingJobs[i].mDefJobId == 0) {
10801             DefWork *dw = new DefWork(cmd, sNextJobId, args);
10802             if (!dw) {
10803                 LOGE("out of memory.");
10804                 return 0;
10805             }
10806             if (mCmdQueue.enqueue(dw)) {
10807                 mDefOngoingJobs[i].mDefJobId = sNextJobId++;
10808                 mDefOngoingJobs[i].mDefJobStatus = 0;
10809                 if (sNextJobId == 0) { // handle overflow
10810                     sNextJobId = 1;
10811                 }
10812                 mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB,
10813                         FALSE,
10814                         FALSE);
10815                 return mDefOngoingJobs[i].mDefJobId;
10816             } else {
10817                 LOGD("Command queue not active! cmd = %d", cmd);
10818                 delete dw;
10819                 return 0;
10820             }
10821         }
10822     }
10823     return 0;
10824 }
10825 
10826 /*===========================================================================
10827  * FUNCTION   : initJpegHandle
10828  *
10829  * DESCRIPTION: Opens JPEG client and gets a handle.
10830  *                     Sends Dual cam calibration info if present
10831  *
10832  * RETURN     : int32_t type of status
10833  *              NO_ERROR  -- success
10834  *              none-zero failure code
10835  *==========================================================================*/
initJpegHandle()10836 int32_t QCamera2HardwareInterface::initJpegHandle() {
10837     // Check if JPEG client handle is present
10838     LOGH("E");
10839     if(!mJpegClientHandle) {
10840         mm_dimension max_size = {0, 0};
10841         cam_dimension_t size;
10842 
10843         mParameters.getMaxPicSize(size);
10844         max_size.w = size.width;
10845         max_size.h = size.height;
10846 
10847         if (getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
10848             if (m_bRelCamCalibValid) {
10849                 mJpegClientHandle = jpeg_open(&mJpegHandle, &mJpegMpoHandle,
10850                         max_size, &mJpegMetadata);
10851             } else {
10852                 mJpegClientHandle =  jpeg_open(&mJpegHandle, &mJpegMpoHandle,
10853                         max_size, NULL);
10854             }
10855         } else {
10856             mJpegClientHandle = jpeg_open(&mJpegHandle, NULL, max_size, NULL);
10857         }
10858         if (!mJpegClientHandle) {
10859             LOGE("Error !! jpeg_open failed!! ");
10860             return UNKNOWN_ERROR;
10861         }
10862         // Set JPEG initialized as true to signify that this camera
10863         // has initialized the handle
10864         mJpegHandleOwner = true;
10865     }
10866     LOGH("X mJpegHandleOwner: %d, mJpegClientHandle: %d camera id: %d",
10867              mJpegHandleOwner, mJpegClientHandle, mCameraId);
10868     return NO_ERROR;
10869 }
10870 
10871 /*===========================================================================
10872  * FUNCTION   : deinitJpegHandle
10873  *
10874  * DESCRIPTION: Closes JPEG client using handle
10875  *
10876  * RETURN     : int32_t type of status
10877  *              NO_ERROR  -- success
10878  *              none-zero failure code
10879  *==========================================================================*/
deinitJpegHandle()10880 int32_t QCamera2HardwareInterface::deinitJpegHandle() {
10881     int32_t rc = NO_ERROR;
10882     LOGH("E");
10883     // Check if JPEG client handle is present and inited by this camera
10884     if(mJpegHandleOwner && mJpegClientHandle) {
10885         rc = mJpegHandle.close(mJpegClientHandle);
10886         if (rc != NO_ERROR) {
10887             LOGE("Error!! Closing mJpegClientHandle: %d failed",
10888                      mJpegClientHandle);
10889         }
10890         memset(&mJpegHandle, 0, sizeof(mJpegHandle));
10891         memset(&mJpegMpoHandle, 0, sizeof(mJpegMpoHandle));
10892         mJpegHandleOwner = false;
10893     }
10894     mJpegClientHandle = 0;
10895     LOGH("X rc = %d", rc);
10896     return rc;
10897 }
10898 
10899 /*===========================================================================
10900  * FUNCTION   : setJpegHandleInfo
10901  *
10902  * DESCRIPTION: sets JPEG client handle info
10903  *
10904  * PARAMETERS:
10905  *                  @ops                    : JPEG ops
10906  *                  @mpo_ops             : Jpeg MPO ops
10907  *                  @pJpegClientHandle : o/p Jpeg Client Handle
10908  *
10909  * RETURN     : int32_t type of status
10910  *              NO_ERROR  -- success
10911  *              none-zero failure code
10912  *==========================================================================*/
setJpegHandleInfo(mm_jpeg_ops_t * ops,mm_jpeg_mpo_ops_t * mpo_ops,uint32_t pJpegClientHandle)10913 int32_t QCamera2HardwareInterface::setJpegHandleInfo(mm_jpeg_ops_t *ops,
10914         mm_jpeg_mpo_ops_t *mpo_ops, uint32_t pJpegClientHandle) {
10915 
10916     if (pJpegClientHandle && ops && mpo_ops) {
10917         LOGH("Setting JPEG client handle %d",
10918                 pJpegClientHandle);
10919         memcpy(&mJpegHandle, ops, sizeof(mm_jpeg_ops_t));
10920         memcpy(&mJpegMpoHandle, mpo_ops, sizeof(mm_jpeg_mpo_ops_t));
10921         mJpegClientHandle = pJpegClientHandle;
10922         return NO_ERROR;
10923     }
10924     else {
10925         LOGE("Error!! No Handle found: %d",
10926                 pJpegClientHandle);
10927         return BAD_VALUE;
10928     }
10929 }
10930 
10931 /*===========================================================================
10932  * FUNCTION   : getJpegHandleInfo
10933  *
10934  * DESCRIPTION: gets JPEG client handle info
10935  *
10936  * PARAMETERS:
10937  *                  @ops                    : JPEG ops
10938  *                  @mpo_ops             : Jpeg MPO ops
10939  *                  @pJpegClientHandle : o/p Jpeg Client Handle
10940  *
10941  * RETURN     : int32_t type of status
10942  *              NO_ERROR  -- success
10943  *              none-zero failure code
10944  *==========================================================================*/
getJpegHandleInfo(mm_jpeg_ops_t * ops,mm_jpeg_mpo_ops_t * mpo_ops,uint32_t * pJpegClientHandle)10945 int32_t QCamera2HardwareInterface::getJpegHandleInfo(mm_jpeg_ops_t *ops,
10946         mm_jpeg_mpo_ops_t *mpo_ops, uint32_t *pJpegClientHandle) {
10947 
10948     if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
10949         LOGE("Init PProc Deferred work failed");
10950         return UNKNOWN_ERROR;
10951     }
10952     // Copy JPEG ops if present
10953     if (ops && mpo_ops && pJpegClientHandle) {
10954         memcpy(ops, &mJpegHandle, sizeof(mm_jpeg_ops_t));
10955         memcpy(mpo_ops, &mJpegMpoHandle, sizeof(mm_jpeg_mpo_ops_t));
10956         *pJpegClientHandle = mJpegClientHandle;
10957         LOGH("Getting JPEG client handle %d",
10958                 pJpegClientHandle);
10959         return NO_ERROR;
10960     } else {
10961         return BAD_VALUE;
10962     }
10963 }
10964 
10965 /*===========================================================================
10966  * FUNCTION   : dequeueDeferredWork
10967  *
10968  * DESCRIPTION: function which dequeues deferred tasks
10969  *
10970  * PARAMETERS :
10971  *   @dw      : deferred work
10972  *   @jobStatus: deferred task job status
10973  *
10974  * RETURN     : int32_t type of status
10975  *              NO_ERROR  -- success
10976  *              none-zero failure code
10977  *==========================================================================*/
dequeueDeferredWork(DefWork * dw,int32_t jobStatus)10978 uint32_t QCamera2HardwareInterface::dequeueDeferredWork(DefWork* dw, int32_t jobStatus)
10979 {
10980     Mutex::Autolock l(mDefLock);
10981     for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) {
10982         if (mDefOngoingJobs[i].mDefJobId == dw->id) {
10983             if (jobStatus != NO_ERROR) {
10984                 mDefOngoingJobs[i].mDefJobStatus = jobStatus;
10985                 LOGH("updating job status %d for id %d",
10986                          jobStatus, dw->id);
10987             } else {
10988                 mDefOngoingJobs[i].mDefJobId = 0;
10989                 mDefOngoingJobs[i].mDefJobStatus = 0;
10990             }
10991             delete dw;
10992             mDefCond.broadcast();
10993             return NO_ERROR;
10994         }
10995     }
10996 
10997     return UNKNOWN_ERROR;
10998 }
10999 
11000 /*===========================================================================
11001  * FUNCTION   : getDefJobStatus
11002  *
11003  * DESCRIPTION: Gets if a deferred task is success/fail
11004  *
11005  * PARAMETERS :
11006  *   @job_id  : deferred task id
11007  *
11008  * RETURN     : NO_ERROR if the job success, otherwise false
11009  *
11010  * PRECONDITION : mDefLock is held by current thread
11011  *==========================================================================*/
getDefJobStatus(uint32_t & job_id)11012 int32_t QCamera2HardwareInterface::getDefJobStatus(uint32_t &job_id)
11013 {
11014     for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) {
11015         if (mDefOngoingJobs[i].mDefJobId == job_id) {
11016             if ( NO_ERROR != mDefOngoingJobs[i].mDefJobStatus ) {
11017                 LOGE("job_id (%d) was failed", job_id);
11018                 return mDefOngoingJobs[i].mDefJobStatus;
11019             }
11020             else
11021                 return NO_ERROR;
11022         }
11023     }
11024     return NO_ERROR;
11025 }
11026 
11027 
11028 /*===========================================================================
11029  * FUNCTION   : checkDeferredWork
11030  *
11031  * DESCRIPTION: checks if a deferred task is in progress
11032  *
11033  * PARAMETERS :
11034  *   @job_id  : deferred task id
11035  *
11036  * RETURN     : true if the task exists, otherwise false
11037  *
11038  * PRECONDITION : mDefLock is held by current thread
11039  *==========================================================================*/
checkDeferredWork(uint32_t & job_id)11040 bool QCamera2HardwareInterface::checkDeferredWork(uint32_t &job_id)
11041 {
11042     for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) {
11043         if (mDefOngoingJobs[i].mDefJobId == job_id) {
11044             return (NO_ERROR == mDefOngoingJobs[i].mDefJobStatus);
11045         }
11046     }
11047     return false;
11048 }
11049 
11050 /*===========================================================================
11051  * FUNCTION   : waitDeferredWork
11052  *
11053  * DESCRIPTION: waits for a deferred task to finish
11054  *
11055  * PARAMETERS :
11056  *   @job_id  : deferred task id
11057  *
11058  * RETURN     : int32_t type of status
11059  *              NO_ERROR  -- success
11060  *              none-zero failure code
11061  *==========================================================================*/
waitDeferredWork(uint32_t & job_id)11062 int32_t QCamera2HardwareInterface::waitDeferredWork(uint32_t &job_id)
11063 {
11064     Mutex::Autolock l(mDefLock);
11065 
11066     if (job_id == 0) {
11067         LOGD("Invalid job id %d", job_id);
11068         return NO_ERROR;
11069     }
11070 
11071     while (checkDeferredWork(job_id) == true ) {
11072         mDefCond.waitRelative(mDefLock, CAMERA_DEFERRED_THREAD_TIMEOUT);
11073     }
11074     return getDefJobStatus(job_id);
11075 }
11076 
11077 /*===========================================================================
11078  * FUNCTION   : scheduleBackgroundTask
11079  *
11080  * DESCRIPTION: Run a requested task in the deferred thread
11081  *
11082  * PARAMETERS :
11083  *   @bgTask  : Task to perform in the background
11084  *
11085  * RETURN     : job id of deferred job
11086  *            : 0 in case of error
11087  *==========================================================================*/
scheduleBackgroundTask(BackgroundTask * bgTask)11088 uint32_t QCamera2HardwareInterface::scheduleBackgroundTask(BackgroundTask* bgTask)
11089 {
11090     DeferWorkArgs args;
11091     memset(&args, 0, sizeof(DeferWorkArgs));
11092     args.genericArgs = bgTask;
11093 
11094     return queueDeferredWork(CMD_DEF_GENERIC, args);
11095 }
11096 
11097 /*===========================================================================
11098  * FUNCTION   : waitForBackgroundTask
11099  *
11100  * DESCRIPTION: Wait for a background task to complete
11101  *
11102  * PARAMETERS :
11103  *   @taskId  : Task id to wait for
11104  *
11105  * RETURN     : int32_t type of status
11106  *              NO_ERROR  -- success
11107  *              none-zero failure code
11108  *==========================================================================*/
waitForBackgroundTask(uint32_t & taskId)11109 int32_t QCamera2HardwareInterface::waitForBackgroundTask(uint32_t& taskId)
11110 {
11111     return waitDeferredWork(taskId);
11112 }
11113 
11114 /*===========================================================================
11115  * FUNCTION   : needDeferedAllocation
11116  *
11117  * DESCRIPTION: Function to decide background task for streams
11118  *
11119  * PARAMETERS :
11120  *   @stream_type  : stream type
11121  *
11122  * RETURN     : true - if background task is needed
11123  *              false -  if background task is NOT needed
11124  *==========================================================================*/
needDeferred(cam_stream_type_t stream_type)11125 bool QCamera2HardwareInterface::needDeferred(cam_stream_type_t stream_type)
11126 {
11127     if ((stream_type == CAM_STREAM_TYPE_PREVIEW && mPreviewWindow == NULL)
11128             || (stream_type == CAM_STREAM_TYPE_ANALYSIS)) {
11129         return FALSE;
11130     }
11131 
11132     if ((stream_type == CAM_STREAM_TYPE_RAW)
11133             && (mParameters.getofflineRAW() && !mParameters.getQuadraCfa())) {
11134         return FALSE;
11135     }
11136 
11137     if ((stream_type == CAM_STREAM_TYPE_SNAPSHOT)
11138             && (!mParameters.getRecordingHintValue())){
11139         return TRUE;
11140     }
11141 
11142     if ((stream_type == CAM_STREAM_TYPE_PREVIEW)
11143             || (stream_type == CAM_STREAM_TYPE_METADATA)
11144             || (stream_type == CAM_STREAM_TYPE_RAW)
11145             || (stream_type == CAM_STREAM_TYPE_POSTVIEW)) {
11146         return TRUE;
11147     }
11148 
11149     if (stream_type == CAM_STREAM_TYPE_VIDEO) {
11150         return FALSE;
11151     }
11152     return FALSE;
11153 }
11154 
11155 /*===========================================================================
11156  * FUNCTION   : needSyncCB
11157  *
11158  * DESCRIPTION: Decide syncronous callback per stream
11159  *
11160  * PARAMETERS :
11161  *  @stream_type: stream type
11162  *
11163  * RETURN     : true - if background task is needed
11164  *              false -  if background task is NOT needed
11165  *==========================================================================*/
needSyncCB(cam_stream_type_t stream_type)11166 bool QCamera2HardwareInterface::needSyncCB(cam_stream_type_t stream_type)
11167 {
11168 #ifdef TARGET_TS_MAKEUP
11169     int whiteLevel, cleanLevel;
11170     if(mParameters.getTsMakeupInfo(whiteLevel, cleanLevel) == TRUE) {
11171         return FALSE;
11172     }
11173 #endif
11174 
11175     char value[PROPERTY_VALUE_MAX];
11176     property_get("persist.camera.preview.sync_cb", value, "1");
11177     if ((atoi(value) == 1) && (stream_type == CAM_STREAM_TYPE_PREVIEW)) {
11178         return TRUE;
11179     }
11180     return FALSE;
11181 }
11182 
11183 /*===========================================================================
11184  * FUNCTION   : isRegularCapture
11185  *
11186  * DESCRIPTION: Check configuration for regular catpure
11187  *
11188  * PARAMETERS :
11189  *
11190  * RETURN     : true - regular capture
11191  *              false - other type of capture
11192  *==========================================================================*/
isRegularCapture()11193 bool QCamera2HardwareInterface::isRegularCapture()
11194 {
11195     bool ret = false;
11196 
11197     if (numOfSnapshotsExpected() == 1 &&
11198         !isLongshotEnabled() &&
11199         !mParameters.isHDREnabled() &&
11200         !mParameters.getRecordingHintValue() &&
11201         !isZSLMode() && (!mParameters.getofflineRAW()|| mParameters.getQuadraCfa())) {
11202             ret = true;
11203     }
11204     return ret;
11205 }
11206 
11207 /*===========================================================================
11208  * FUNCTION   : needOfflineReprocessing
11209  *
11210  * DESCRIPTION: Check for offline reprocessing
11211  *
11212  * PARAMETERS :
11213  *
11214  * RETURN     : true - regular capture
11215  *              false - other type of capture
11216  *==========================================================================*/
needOfflineReprocessing()11217 bool QCamera2HardwareInterface::needOfflineReprocessing()
11218 {
11219     bool ret = false;
11220     if (isRegularCapture()
11221             || isDualCamera()) {
11222         ret = true;
11223     }
11224     return ret;
11225 }
11226 
11227 /*===========================================================================
11228  * FUNCTION   : getLogLevel
11229  *
11230  * DESCRIPTION: Reads the log level property into a variable
11231  *
11232  * PARAMETERS :
11233  *   None
11234  *
11235  * RETURN     :
11236  *   None
11237  *==========================================================================*/
getLogLevel()11238 void QCamera2HardwareInterface::getLogLevel()
11239 {
11240     char prop[PROPERTY_VALUE_MAX];
11241 
11242     property_get("persist.camera.kpi.debug", prop, "0");
11243     gKpiDebugLevel = atoi(prop);
11244     return;
11245 }
11246 
11247 /*===========================================================================
11248  * FUNCTION   : getSensorType
11249  *
11250  * DESCRIPTION: Returns the type of sensor being used whether YUV or Bayer
11251  *
11252  * PARAMETERS :
11253  *   None
11254  *
11255  * RETURN     : Type of sensor - bayer or YUV
11256  *
11257  *==========================================================================*/
getSensorType()11258 cam_sensor_t QCamera2HardwareInterface::getSensorType()
11259 {
11260     return gCamCapability[mCameraId]->sensor_type.sens_type;
11261 }
11262 
11263 /*===========================================================================
11264  * FUNCTION   : startRAWChannel
11265  *
11266  * DESCRIPTION: start RAW Channel
11267  *
11268  * PARAMETERS :
11269  *   @pChannel  : Src channel to link this RAW channel.
11270  *
11271  * RETURN     : int32_t type of status
11272  *              NO_ERROR  -- success
11273  *              none-zero failure code
11274  *==========================================================================*/
startRAWChannel(QCameraChannel * pMetaChannel)11275 int32_t QCamera2HardwareInterface::startRAWChannel(QCameraChannel *pMetaChannel)
11276 {
11277     int32_t rc = NO_ERROR;
11278     QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_RAW];
11279     if ((NULL != pChannel) && (mParameters.getofflineRAW())) {
11280         // Find and try to link a metadata stream from preview channel
11281         QCameraStream *pMetaStream = NULL;
11282 
11283         if (pMetaChannel != NULL) {
11284             uint32_t streamNum = pMetaChannel->getNumOfStreams();
11285             QCameraStream *pStream = NULL;
11286             for (uint32_t i = 0 ; i < streamNum ; i++ ) {
11287                 pStream = pMetaChannel->getStreamByIndex(i);
11288                 if ((NULL != pStream) &&
11289                         (CAM_STREAM_TYPE_METADATA == pStream->getMyType())) {
11290                     pMetaStream = pStream;
11291                     break;
11292                 }
11293             }
11294 
11295             if (NULL != pMetaStream) {
11296                 rc = pChannel->linkStream(pMetaChannel, pMetaStream);
11297                 if (NO_ERROR != rc) {
11298                     LOGE("Metadata stream link failed %d", rc);
11299                 }
11300             }
11301         }
11302         rc = pChannel->start();
11303     }
11304     return rc;
11305 }
11306 
11307 /*===========================================================================
11308  * FUNCTION   : startRecording
11309  *
11310  * DESCRIPTION: start recording impl
11311  *
11312  * PARAMETERS : none
11313  *
11314  * RETURN     : int32_t type of status
11315  *              NO_ERROR  -- success
11316  *              none-zero failure code
11317  *==========================================================================*/
stopRAWChannel()11318 int32_t QCamera2HardwareInterface::stopRAWChannel()
11319 {
11320     int32_t rc = NO_ERROR;
11321     rc = stopChannel(QCAMERA_CH_TYPE_RAW);
11322     return rc;
11323 }
11324 
11325 /*===========================================================================
11326  * FUNCTION   : isLowPowerMode
11327  *
11328  * DESCRIPTION: Returns TRUE if low power mode settings are to be applied for video recording
11329  *
11330  * PARAMETERS :
11331  *   None
11332  *
11333  * RETURN     : TRUE/FALSE
11334  *
11335  *==========================================================================*/
isLowPowerMode()11336 bool QCamera2HardwareInterface::isLowPowerMode()
11337 {
11338     cam_dimension_t dim;
11339     mParameters.getStreamDimension(CAM_STREAM_TYPE_VIDEO, dim);
11340 
11341     char prop[PROPERTY_VALUE_MAX];
11342     property_get("camera.lowpower.record.enable", prop, "0");
11343     int enable = atoi(prop);
11344 
11345     //Enable low power mode if :
11346     //1. Video resolution is 2k (2048x1080) or above and
11347     //2. camera.lowpower.record.enable is set
11348 
11349     bool isLowpower = mParameters.getRecordingHintValue() && enable
11350             && ((dim.width * dim.height) >= (2048 * 1080));
11351     return isLowpower;
11352 }
11353 
11354 /*===========================================================================
11355  * FUNCTION   : getBootToMonoTimeOffset
11356  *
11357  * DESCRIPTION: Calculate offset that is used to convert from
11358  *              clock domain of boot to monotonic
11359  *
11360  * PARAMETERS :
11361  *   None
11362  *
11363  * RETURN     : clock offset between boottime and monotonic time.
11364  *
11365  *==========================================================================*/
getBootToMonoTimeOffset()11366 nsecs_t QCamera2HardwareInterface::getBootToMonoTimeOffset()
11367 {
11368     // try three times to get the clock offset, choose the one
11369     // with the minimum gap in measurements.
11370     const int tries = 3;
11371     nsecs_t bestGap, measured;
11372     for (int i = 0; i < tries; ++i) {
11373         const nsecs_t tmono = systemTime(SYSTEM_TIME_MONOTONIC);
11374         const nsecs_t tbase = systemTime(SYSTEM_TIME_BOOTTIME);
11375         const nsecs_t tmono2 = systemTime(SYSTEM_TIME_MONOTONIC);
11376         const nsecs_t gap = tmono2 - tmono;
11377         if (i == 0 || gap < bestGap) {
11378             bestGap = gap;
11379             measured = tbase - ((tmono + tmono2) >> 1);
11380         }
11381     }
11382     return measured;
11383 }
11384 
11385 /*===========================================================================
11386  * FUNCTION   : fillDualCameraFOVControl
11387  *
11388  * DESCRIPTION: Function to process FOV ctrl event from statemachine thread.
11389  *
11390  * PARAMETERS : none
11391  *
11392  * RETURN     : none
11393  *==========================================================================*/
fillDualCameraFOVControl()11394 void QCamera2HardwareInterface::fillDualCameraFOVControl()
11395 {
11396     qcamera_sm_internal_evt_payload_t *payload =
11397        (qcamera_sm_internal_evt_payload_t *)
11398        malloc(sizeof(qcamera_sm_internal_evt_payload_t));
11399     if (NULL != payload) {
11400         memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
11401         payload->evt_type = QCAMERA_INTERNAL_EVT_DUAL_CAMERA_FOV_CONTROL;
11402         int32_t rc = processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
11403         if (rc != NO_ERROR) {
11404             LOGE("processEvt Dual camera fill FOV control failed");
11405             free(payload);
11406             payload = NULL;
11407         }
11408     } else {
11409         LOGE("No memory for Dual camera fill FOV control event");
11410     }
11411 }
11412 
11413 }; // namespace qcamera
11414