1 /* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 *     * Redistributions of source code must retain the above copyright
7 *       notice, this list of conditions and the following disclaimer.
8 *     * Redistributions in binary form must reproduce the above
9 *       copyright notice, this list of conditions and the following
10 *       disclaimer in the documentation and/or other materials provided
11 *       with the distribution.
12 *     * Neither the name of The Linux Foundation nor the names of its
13 *       contributors may be used to endorse or promote products derived
14 *       from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29 
30 #define LOG_TAG "QCamera2HWI"
31 
32 // To remove
33 #include <cutils/properties.h>
34 
35 // System definitions
36 #include <utils/Errors.h>
37 #include <dlfcn.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include "gralloc_priv.h"
41 #include "native_handle.h"
42 
43 // Camera definitions
44 #include "android/QCamera2External.h"
45 #include "QCamera2HWI.h"
46 #include "QCameraBufferMaps.h"
47 #include "QCameraFlash.h"
48 #include "QCameraTrace.h"
49 
50 extern "C" {
51 #include "mm_camera_dbg.h"
52 }
53 
54 #define MAP_TO_DRIVER_COORDINATE(val, base, scale, offset) \
55     ((int32_t)val * (int32_t)scale / (int32_t)base + (int32_t)offset)
56 #define CAMERA_MIN_STREAMING_BUFFERS     3
57 #define EXTRA_ZSL_PREVIEW_STREAM_BUF     2
58 #define CAMERA_MIN_JPEG_ENCODING_BUFFERS 2
59 #define CAMERA_MIN_VIDEO_BUFFERS         9
60 #define CAMERA_MIN_CALLBACK_BUFFERS      5
61 #define CAMERA_LONGSHOT_STAGES           4
62 #define CAMERA_MIN_CAMERA_BATCH_BUFFERS  6
63 #define CAMERA_ISP_PING_PONG_BUFFERS     2
64 #define MIN_UNDEQUEUED_BUFFERS           1 // This is required if preview window is not set
65 
66 #define HDR_CONFIDENCE_THRESHOLD 0.4
67 
68 #define CAMERA_OPEN_PERF_TIME_OUT 500 // 500 milliseconds
69 
70 // Very long wait, just to be sure we don't deadlock
71 #define CAMERA_DEFERRED_THREAD_TIMEOUT 5000000000 // 5 seconds
72 #define CAMERA_DEFERRED_MAP_BUF_TIMEOUT 2000000000 // 2 seconds
73 #define CAMERA_MIN_METADATA_BUFFERS 10 // Need at least 10 for ZSL snapshot
74 #define CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS 5
75 #define CAMERA_MAX_PARAM_APPLY_DELAY 3
76 
77 namespace qcamera {
78 
79 extern cam_capability_t *gCamCapability[MM_CAMERA_MAX_NUM_SENSORS];
80 extern pthread_mutex_t gCamLock;
81 volatile uint32_t gCamHalLogLevel = 1;
82 extern uint8_t gNumCameraSessions;
83 uint32_t QCamera2HardwareInterface::sNextJobId = 1;
84 
85 camera_device_ops_t QCamera2HardwareInterface::mCameraOps = {
86     .set_preview_window =        QCamera2HardwareInterface::set_preview_window,
87     .set_callbacks =             QCamera2HardwareInterface::set_CallBacks,
88     .enable_msg_type =           QCamera2HardwareInterface::enable_msg_type,
89     .disable_msg_type =          QCamera2HardwareInterface::disable_msg_type,
90     .msg_type_enabled =          QCamera2HardwareInterface::msg_type_enabled,
91 
92     .start_preview =             QCamera2HardwareInterface::start_preview,
93     .stop_preview =              QCamera2HardwareInterface::stop_preview,
94     .preview_enabled =           QCamera2HardwareInterface::preview_enabled,
95     .store_meta_data_in_buffers= QCamera2HardwareInterface::store_meta_data_in_buffers,
96 
97     .start_recording =           QCamera2HardwareInterface::start_recording,
98     .stop_recording =            QCamera2HardwareInterface::stop_recording,
99     .recording_enabled =         QCamera2HardwareInterface::recording_enabled,
100     .release_recording_frame =   QCamera2HardwareInterface::release_recording_frame,
101 
102     .auto_focus =                QCamera2HardwareInterface::auto_focus,
103     .cancel_auto_focus =         QCamera2HardwareInterface::cancel_auto_focus,
104 
105     .take_picture =              QCamera2HardwareInterface::take_picture,
106     .cancel_picture =            QCamera2HardwareInterface::cancel_picture,
107 
108     .set_parameters =            QCamera2HardwareInterface::set_parameters,
109     .get_parameters =            QCamera2HardwareInterface::get_parameters,
110     .put_parameters =            QCamera2HardwareInterface::put_parameters,
111     .send_command =              QCamera2HardwareInterface::send_command,
112 
113     .release =                   QCamera2HardwareInterface::release,
114     .dump =                      QCamera2HardwareInterface::dump,
115 };
116 
117 /*===========================================================================
118  * FUNCTION   : set_preview_window
119  *
120  * DESCRIPTION: set preview window.
121  *
122  * PARAMETERS :
123  *   @device  : ptr to camera device struct
124  *   @window  : window ops table
125  *
126  * RETURN     : int32_t type of status
127  *              NO_ERROR  -- success
128  *              none-zero failure code
129  *==========================================================================*/
set_preview_window(struct camera_device * device,struct preview_stream_ops * window)130 int QCamera2HardwareInterface::set_preview_window(struct camera_device *device,
131         struct preview_stream_ops *window)
132 {
133     ATRACE_CALL();
134     int rc = NO_ERROR;
135     QCamera2HardwareInterface *hw =
136         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
137     if (!hw) {
138         LOGE("NULL camera device");
139         return BAD_VALUE;
140     }
141     LOGD("E camera id %d window = %p", hw->getCameraId(), window);
142 
143     hw->lockAPI();
144     qcamera_api_result_t apiResult;
145     rc = hw->processAPI(QCAMERA_SM_EVT_SET_PREVIEW_WINDOW, (void *)window);
146     if (rc == NO_ERROR) {
147         hw->waitAPIResult(QCAMERA_SM_EVT_SET_PREVIEW_WINDOW, &apiResult);
148         rc = apiResult.status;
149     }
150     hw->unlockAPI();
151     LOGD("X camera id %d", hw->getCameraId());
152 
153     return rc;
154 }
155 
156 /*===========================================================================
157  * FUNCTION   : set_CallBacks
158  *
159  * DESCRIPTION: set callbacks for notify and data
160  *
161  * PARAMETERS :
162  *   @device     : ptr to camera device struct
163  *   @notify_cb  : notify cb
164  *   @data_cb    : data cb
165  *   @data_cb_timestamp  : video data cd with timestamp
166  *   @get_memory : ops table for request gralloc memory
167  *   @user       : user data ptr
168  *
169  * RETURN     : none
170  *==========================================================================*/
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)171 void QCamera2HardwareInterface::set_CallBacks(struct camera_device *device,
172         camera_notify_callback notify_cb,
173         camera_data_callback data_cb,
174         camera_data_timestamp_callback data_cb_timestamp,
175         camera_request_memory get_memory,
176         void *user)
177 {
178     ATRACE_CALL();
179     QCamera2HardwareInterface *hw =
180         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
181     if (!hw) {
182         LOGE("NULL camera device");
183         return;
184     }
185     LOGD("E camera id %d", hw->getCameraId());
186 
187     qcamera_sm_evt_setcb_payload_t payload;
188     payload.notify_cb = notify_cb;
189     payload.data_cb = data_cb;
190     payload.data_cb_timestamp = data_cb_timestamp;
191     payload.get_memory = get_memory;
192     payload.user = user;
193 
194     hw->lockAPI();
195     qcamera_api_result_t apiResult;
196     int32_t rc = hw->processAPI(QCAMERA_SM_EVT_SET_CALLBACKS, (void *)&payload);
197     if (rc == NO_ERROR) {
198         hw->waitAPIResult(QCAMERA_SM_EVT_SET_CALLBACKS, &apiResult);
199     }
200     hw->unlockAPI();
201     LOGD("X camera id %d", hw->getCameraId());
202 
203 }
204 
205 /*===========================================================================
206  * FUNCTION   : enable_msg_type
207  *
208  * DESCRIPTION: enable certain msg type
209  *
210  * PARAMETERS :
211  *   @device     : ptr to camera device struct
212  *   @msg_type   : msg type mask
213  *
214  * RETURN     : none
215  *==========================================================================*/
enable_msg_type(struct camera_device * device,int32_t msg_type)216 void QCamera2HardwareInterface::enable_msg_type(struct camera_device *device, int32_t msg_type)
217 {
218     ATRACE_CALL();
219     QCamera2HardwareInterface *hw =
220         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
221     if (!hw) {
222         LOGE("NULL camera device");
223         return;
224     }
225     LOGD("E camera id %d", hw->getCameraId());
226 
227     hw->lockAPI();
228     qcamera_api_result_t apiResult;
229     int32_t rc = hw->processAPI(QCAMERA_SM_EVT_ENABLE_MSG_TYPE, (void *)&msg_type);
230     if (rc == NO_ERROR) {
231         hw->waitAPIResult(QCAMERA_SM_EVT_ENABLE_MSG_TYPE, &apiResult);
232     }
233     hw->unlockAPI();
234     LOGD("X camera id %d", hw->getCameraId());
235 
236 }
237 
238 /*===========================================================================
239  * FUNCTION   : disable_msg_type
240  *
241  * DESCRIPTION: disable certain msg type
242  *
243  * PARAMETERS :
244  *   @device     : ptr to camera device struct
245  *   @msg_type   : msg type mask
246  *
247  * RETURN     : none
248  *==========================================================================*/
disable_msg_type(struct camera_device * device,int32_t msg_type)249 void QCamera2HardwareInterface::disable_msg_type(struct camera_device *device, int32_t msg_type)
250 {
251     ATRACE_CALL();
252     QCamera2HardwareInterface *hw =
253         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
254     if (!hw) {
255         LOGE("NULL camera device");
256         return;
257     }
258     LOGD("E camera id %d", hw->getCameraId());
259 
260     hw->lockAPI();
261     qcamera_api_result_t apiResult;
262     int32_t rc = hw->processAPI(QCAMERA_SM_EVT_DISABLE_MSG_TYPE, (void *)&msg_type);
263     if (rc == NO_ERROR) {
264         hw->waitAPIResult(QCAMERA_SM_EVT_DISABLE_MSG_TYPE, &apiResult);
265     }
266     hw->unlockAPI();
267     LOGD("X camera id %d", hw->getCameraId());
268 
269 }
270 
271 /*===========================================================================
272  * FUNCTION   : msg_type_enabled
273  *
274  * DESCRIPTION: if certain msg type is enabled
275  *
276  * PARAMETERS :
277  *   @device     : ptr to camera device struct
278  *   @msg_type   : msg type mask
279  *
280  * RETURN     : 1 -- enabled
281  *              0 -- not enabled
282  *==========================================================================*/
msg_type_enabled(struct camera_device * device,int32_t msg_type)283 int QCamera2HardwareInterface::msg_type_enabled(struct camera_device *device, int32_t msg_type)
284 {
285     ATRACE_CALL();
286     int ret = NO_ERROR;
287     QCamera2HardwareInterface *hw =
288         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
289     if (!hw) {
290         LOGE("NULL camera device");
291         return BAD_VALUE;
292     }
293     LOGD("E camera id %d", hw->getCameraId());
294 
295     hw->lockAPI();
296     qcamera_api_result_t apiResult;
297     ret = hw->processAPI(QCAMERA_SM_EVT_MSG_TYPE_ENABLED, (void *)&msg_type);
298     if (ret == NO_ERROR) {
299         hw->waitAPIResult(QCAMERA_SM_EVT_MSG_TYPE_ENABLED, &apiResult);
300         ret = apiResult.enabled;
301     }
302     hw->unlockAPI();
303     LOGD("X camera id %d", hw->getCameraId());
304 
305    return ret;
306 }
307 
308 /*===========================================================================
309  * FUNCTION   : prepare_preview
310  *
311  * DESCRIPTION: prepare preview
312  *
313  * PARAMETERS :
314  *   @device  : ptr to camera device struct
315  *
316  * RETURN     : int32_t type of status
317  *              NO_ERROR  -- success
318  *              none-zero failure code
319  *==========================================================================*/
prepare_preview(struct camera_device * device)320 int QCamera2HardwareInterface::prepare_preview(struct camera_device *device)
321 {
322     ATRACE_CALL();
323     int ret = NO_ERROR;
324     QCamera2HardwareInterface *hw =
325         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
326     if (!hw) {
327         LOGE("NULL camera device");
328         return BAD_VALUE;
329     }
330     LOGH("[KPI Perf]: E PROFILE_PREPARE_PREVIEW camera id %d",
331              hw->getCameraId());
332     hw->lockAPI();
333     qcamera_api_result_t apiResult;
334     qcamera_sm_evt_enum_t evt = QCAMERA_SM_EVT_PREPARE_PREVIEW;
335     ret = hw->processAPI(evt, NULL);
336     if (ret == NO_ERROR) {
337         hw->waitAPIResult(evt, &apiResult);
338         ret = apiResult.status;
339     }
340     hw->unlockAPI();
341     LOGH("[KPI Perf]: X");
342     return ret;
343 }
344 
345 
346 /*===========================================================================
347  * FUNCTION   : start_preview
348  *
349  * DESCRIPTION: start preview
350  *
351  * PARAMETERS :
352  *   @device  : ptr to camera device struct
353  *
354  * RETURN     : int32_t type of status
355  *              NO_ERROR  -- success
356  *              none-zero failure code
357  *==========================================================================*/
start_preview(struct camera_device * device)358 int QCamera2HardwareInterface::start_preview(struct camera_device *device)
359 {
360     KPI_ATRACE_CALL();
361     int ret = NO_ERROR;
362     QCamera2HardwareInterface *hw =
363         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
364     if (!hw) {
365         LOGE("NULL camera device");
366         return BAD_VALUE;
367     }
368     LOGI("[KPI Perf]: E PROFILE_START_PREVIEW camera id %d",
369              hw->getCameraId());
370 
371     // Release the timed perf lock acquired in openCamera
372     hw->m_perfLock.lock_rel_timed();
373 
374     hw->m_perfLock.lock_acq();
375     hw->lockAPI();
376     qcamera_api_result_t apiResult;
377     qcamera_sm_evt_enum_t evt = QCAMERA_SM_EVT_START_PREVIEW;
378     if (hw->isNoDisplayMode()) {
379         evt = QCAMERA_SM_EVT_START_NODISPLAY_PREVIEW;
380     }
381     ret = hw->processAPI(evt, NULL);
382     if (ret == NO_ERROR) {
383         hw->waitAPIResult(evt, &apiResult);
384         ret = apiResult.status;
385     }
386     hw->unlockAPI();
387     hw->m_bPreviewStarted = true;
388     LOGI("[KPI Perf]: X ret = %d", ret);
389     return ret;
390 }
391 
392 /*===========================================================================
393  * FUNCTION   : stop_preview
394  *
395  * DESCRIPTION: stop preview
396  *
397  * PARAMETERS :
398  *   @device  : ptr to camera device struct
399  *
400  * RETURN     : none
401  *==========================================================================*/
stop_preview(struct camera_device * device)402 void QCamera2HardwareInterface::stop_preview(struct camera_device *device)
403 {
404     KPI_ATRACE_CALL();
405     QCamera2HardwareInterface *hw =
406         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
407     if (!hw) {
408         LOGE("NULL camera device");
409         return;
410     }
411     LOGI("[KPI Perf]: E PROFILE_STOP_PREVIEW camera id %d",
412              hw->getCameraId());
413 
414     // Disable power Hint for preview
415     hw->m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, false);
416 
417     hw->m_perfLock.lock_acq();
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_CALL();
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_CALL();
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_CALL();
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_CALL();
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_CALL();
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     LOGI("[KPI Perf]: E PROFILE_START_RECORDING camera id %d",
653           hw->getCameraId());
654     // Give HWI control to call pre_start_recording in single camera mode.
655     // In dual-cam mode, this control belongs to muxer.
656     if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
657         ret = pre_start_recording(device);
658         if (ret != NO_ERROR) {
659             LOGE("pre_start_recording failed with ret = %d", ret);
660             return ret;
661         }
662     }
663 
664     hw->lockAPI();
665     qcamera_api_result_t apiResult;
666     ret = hw->processAPI(QCAMERA_SM_EVT_START_RECORDING, NULL);
667     if (ret == NO_ERROR) {
668         hw->waitAPIResult(QCAMERA_SM_EVT_START_RECORDING, &apiResult);
669         ret = apiResult.status;
670     }
671     hw->unlockAPI();
672     hw->m_bRecordStarted = true;
673     LOGI("[KPI Perf]: X ret = %d", ret);
674 
675     return ret;
676 }
677 
678 /*===========================================================================
679  * FUNCTION   : stop_recording
680  *
681  * DESCRIPTION: stop recording
682  *
683  * PARAMETERS :
684  *   @device  : ptr to camera device struct
685  *
686  * RETURN     : none
687  *==========================================================================*/
stop_recording(struct camera_device * device)688 void QCamera2HardwareInterface::stop_recording(struct camera_device *device)
689 {
690     ATRACE_CALL();
691     QCamera2HardwareInterface *hw =
692         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
693     if (!hw) {
694         LOGE("NULL camera device");
695         return;
696     }
697     LOGI("[KPI Perf]: E PROFILE_STOP_RECORDING camera id %d",
698              hw->getCameraId());
699 
700     hw->lockAPI();
701     qcamera_api_result_t apiResult;
702     int32_t ret = hw->processAPI(QCAMERA_SM_EVT_STOP_RECORDING, NULL);
703     if (ret == NO_ERROR) {
704         hw->waitAPIResult(QCAMERA_SM_EVT_STOP_RECORDING, &apiResult);
705     }
706     hw->unlockAPI();
707     LOGI("[KPI Perf]: X ret = %d", ret);
708 }
709 
710 /*===========================================================================
711  * FUNCTION   : recording_enabled
712  *
713  * DESCRIPTION: if recording is running
714  *
715  * PARAMETERS :
716  *   @device  : ptr to camera device struct
717  *
718  * RETURN     : 1 -- running
719  *              0 -- not running
720  *==========================================================================*/
recording_enabled(struct camera_device * device)721 int QCamera2HardwareInterface::recording_enabled(struct camera_device *device)
722 {
723     ATRACE_CALL();
724     int ret = NO_ERROR;
725     QCamera2HardwareInterface *hw =
726         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
727     if (!hw) {
728         LOGE("NULL camera device");
729         return BAD_VALUE;
730     }
731     LOGD("E camera id %d", hw->getCameraId());
732     hw->lockAPI();
733     qcamera_api_result_t apiResult;
734     ret = hw->processAPI(QCAMERA_SM_EVT_RECORDING_ENABLED, NULL);
735     if (ret == NO_ERROR) {
736         hw->waitAPIResult(QCAMERA_SM_EVT_RECORDING_ENABLED, &apiResult);
737         ret = apiResult.enabled;
738     }
739     hw->unlockAPI();
740     LOGD("X camera id %d", hw->getCameraId());
741 
742     return ret;
743 }
744 
745 /*===========================================================================
746  * FUNCTION   : release_recording_frame
747  *
748  * DESCRIPTION: return recording frame back
749  *
750  * PARAMETERS :
751  *   @device  : ptr to camera device struct
752  *   @opaque  : ptr to frame to be returned
753  *
754  * RETURN     : none
755  *==========================================================================*/
release_recording_frame(struct camera_device * device,const void * opaque)756 void QCamera2HardwareInterface::release_recording_frame(
757             struct camera_device *device, const void *opaque)
758 {
759     ATRACE_CALL();
760     QCamera2HardwareInterface *hw =
761         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
762     if (!hw) {
763         LOGE("NULL camera device");
764         return;
765     }
766     if (!opaque) {
767         LOGE("Error!! Frame info is NULL");
768         return;
769     }
770     LOGD("E camera id %d", hw->getCameraId());
771     hw->lockAPI();
772     qcamera_api_result_t apiResult;
773     int32_t ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, (void *)opaque);
774     if (ret == NO_ERROR) {
775         hw->waitAPIResult(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, &apiResult);
776     }
777     hw->unlockAPI();
778     LOGD("X camera id %d", hw->getCameraId());
779 }
780 
781 /*===========================================================================
782  * FUNCTION   : auto_focus
783  *
784  * DESCRIPTION: start auto focus
785  *
786  * PARAMETERS :
787  *   @device  : ptr to camera device struct
788  *
789  * RETURN     : int32_t type of status
790  *              NO_ERROR  -- success
791  *              none-zero failure code
792  *==========================================================================*/
auto_focus(struct camera_device * device)793 int QCamera2HardwareInterface::auto_focus(struct camera_device *device)
794 {
795     KPI_ATRACE_INT("Camera:AutoFocus", 1);
796     int ret = NO_ERROR;
797     QCamera2HardwareInterface *hw =
798         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
799     if (!hw) {
800         LOGE("NULL camera device");
801         return BAD_VALUE;
802     }
803     LOGH("[KPI Perf] : E PROFILE_AUTO_FOCUS camera id %d",
804              hw->getCameraId());
805     hw->lockAPI();
806     qcamera_api_result_t apiResult;
807     ret = hw->processAPI(QCAMERA_SM_EVT_START_AUTO_FOCUS, NULL);
808     if (ret == NO_ERROR) {
809         hw->waitAPIResult(QCAMERA_SM_EVT_START_AUTO_FOCUS, &apiResult);
810         ret = apiResult.status;
811     }
812     hw->unlockAPI();
813     LOGH("[KPI Perf] : X ret = %d", ret);
814 
815     return ret;
816 }
817 
818 /*===========================================================================
819  * FUNCTION   : cancel_auto_focus
820  *
821  * DESCRIPTION: cancel auto focus
822  *
823  * PARAMETERS :
824  *   @device  : ptr to camera device struct
825  *
826  * RETURN     : int32_t type of status
827  *              NO_ERROR  -- success
828  *              none-zero failure code
829  *==========================================================================*/
cancel_auto_focus(struct camera_device * device)830 int QCamera2HardwareInterface::cancel_auto_focus(struct camera_device *device)
831 {
832     ATRACE_CALL();
833     int ret = NO_ERROR;
834     QCamera2HardwareInterface *hw =
835         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
836     if (!hw) {
837         LOGE("NULL camera device");
838         return BAD_VALUE;
839     }
840     LOGH("[KPI Perf] : E PROFILE_CANCEL_AUTO_FOCUS camera id %d",
841              hw->getCameraId());
842     hw->lockAPI();
843     qcamera_api_result_t apiResult;
844     ret = hw->processAPI(QCAMERA_SM_EVT_STOP_AUTO_FOCUS, NULL);
845     if (ret == NO_ERROR) {
846         hw->waitAPIResult(QCAMERA_SM_EVT_STOP_AUTO_FOCUS, &apiResult);
847         ret = apiResult.status;
848     }
849     hw->unlockAPI();
850     LOGH("[KPI Perf] : X ret = %d", ret);
851     return ret;
852 }
853 
854 /*===========================================================================
855  * FUNCTION   : pre_take_picture
856  *
857  * DESCRIPTION: pre take picture, restart preview if necessary.
858  *
859  * PARAMETERS :
860  *   @device  : ptr to camera device struct
861  *
862  * RETURN     : int32_t type of status
863  *              NO_ERROR  -- success
864  *              none-zero failure code
865  *==========================================================================*/
pre_take_picture(struct camera_device * device)866 int QCamera2HardwareInterface::pre_take_picture(struct camera_device *device)
867 {
868     ATRACE_CALL();
869     int ret = NO_ERROR;
870     QCamera2HardwareInterface *hw =
871         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
872     if (!hw) {
873         LOGE("NULL camera device");
874         return BAD_VALUE;
875     }
876     LOGH("[KPI Perf]: E PROFILE_PRE_TAKE_PICTURE camera id %d",
877           hw->getCameraId());
878     hw->lockAPI();
879     qcamera_api_result_t apiResult;
880     ret = hw->processAPI(QCAMERA_SM_EVT_PRE_TAKE_PICTURE, NULL);
881     if (ret == NO_ERROR) {
882         hw->waitAPIResult(QCAMERA_SM_EVT_PRE_TAKE_PICTURE, &apiResult);
883         ret = apiResult.status;
884     }
885     hw->unlockAPI();
886     LOGH("[KPI Perf]: X");
887     return ret;
888 }
889 
890 /*===========================================================================
891  * FUNCTION   : take_picture
892  *
893  * DESCRIPTION: take picture
894  *
895  * PARAMETERS :
896  *   @device  : ptr to camera device struct
897  *
898  * RETURN     : int32_t type of status
899  *              NO_ERROR  -- success
900  *              none-zero failure code
901  *==========================================================================*/
take_picture(struct camera_device * device)902 int QCamera2HardwareInterface::take_picture(struct camera_device *device)
903 {
904     KPI_ATRACE_CALL();
905     int ret = NO_ERROR;
906     QCamera2HardwareInterface *hw =
907         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
908     if (!hw) {
909         LOGE("NULL camera device");
910         return BAD_VALUE;
911     }
912     LOGI("[KPI Perf]: E PROFILE_TAKE_PICTURE camera id %d",
913              hw->getCameraId());
914     if (!hw->mLongshotEnabled) {
915         hw->m_perfLock.lock_acq();
916     }
917     qcamera_api_result_t apiResult;
918 
919    /** Added support for Retro-active Frames:
920      *  takePicture() is called before preparing Snapshot to indicate the
921      *  mm-camera-channel to pick up legacy frames even
922      *  before LED estimation is triggered.
923      */
924 
925     LOGH("isLiveSnap %d, isZSL %d, isHDR %d longshot = %d",
926            hw->isLiveSnapshot(), hw->isZSLMode(), hw->isHDRMode(),
927            hw->isLongshotEnabled());
928 
929     // Check for Retro-active Frames
930     if ((hw->mParameters.getNumOfRetroSnapshots() > 0) &&
931         !hw->isLiveSnapshot() && hw->isZSLMode() &&
932         !hw->isHDRMode() && !hw->isLongshotEnabled()) {
933         // Set Retro Picture Mode
934         hw->setRetroPicture(1);
935         hw->m_bLedAfAecLock = 0;
936         LOGL("Retro Enabled");
937 
938         // Give HWI control to call pre_take_picture in single camera mode.
939         // In dual-cam mode, this control belongs to muxer.
940         if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
941             ret = pre_take_picture(device);
942             if (ret != NO_ERROR) {
943                 LOGE("pre_take_picture failed with ret = %d",ret);
944                 return ret;
945             }
946         }
947 
948         /* Call take Picture for total number of snapshots required.
949              This includes the number of retro frames and normal frames */
950         hw->lockAPI();
951         ret = hw->processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL);
952         if (ret == NO_ERROR) {
953           // Wait for retro frames, before calling prepare snapshot
954           LOGD("Wait for Retro frames to be done");
955           hw->waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult);
956             ret = apiResult.status;
957         }
958         /* Unlock API since it is acquired in prepare snapshot seperately */
959         hw->unlockAPI();
960 
961         /* Prepare snapshot in case LED needs to be flashed */
962         LOGD("Start Prepare Snapshot");
963         ret = hw->prepare_snapshot(device);
964     }
965     else {
966         hw->setRetroPicture(0);
967         // Check if prepare snapshot is done
968         if (!hw->mPrepSnapRun) {
969             // Ignore the status from prepare_snapshot
970             hw->prepare_snapshot(device);
971         }
972 
973         // Give HWI control to call pre_take_picture in single camera mode.
974         // In dual-cam mode, this control belongs to muxer.
975         if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
976             ret = pre_take_picture(device);
977             if (ret != NO_ERROR) {
978                 LOGE("pre_take_picture failed with ret = %d",ret);
979                 return ret;
980             }
981         }
982 
983         // Regardless what the result value for prepare_snapshot,
984         // go ahead with capture anyway. Just like the way autofocus
985         // is handled in capture case
986         /* capture */
987         LOGL("Capturing normal frames");
988         hw->lockAPI();
989         ret = hw->processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL);
990         if (ret == NO_ERROR) {
991           hw->waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult);
992             ret = apiResult.status;
993         }
994         hw->unlockAPI();
995         if (!hw->isLongshotEnabled()){
996             // For longshot mode, we prepare snapshot only once
997             hw->mPrepSnapRun = false;
998          }
999     }
1000     LOGI("[KPI Perf]: X ret = %d", ret);
1001     return ret;
1002 }
1003 
1004 /*===========================================================================
1005  * FUNCTION   : cancel_picture
1006  *
1007  * DESCRIPTION: cancel current take picture request
1008  *
1009  * PARAMETERS :
1010  *   @device  : ptr to camera device struct
1011  *
1012  * RETURN     : int32_t type of status
1013  *              NO_ERROR  -- success
1014  *              none-zero failure code
1015  *==========================================================================*/
cancel_picture(struct camera_device * device)1016 int QCamera2HardwareInterface::cancel_picture(struct camera_device *device)
1017 {
1018     ATRACE_CALL();
1019     int ret = NO_ERROR;
1020     QCamera2HardwareInterface *hw =
1021         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1022     if (!hw) {
1023         LOGE("NULL camera device");
1024         return BAD_VALUE;
1025     }
1026     LOGI("[KPI Perf]: E PROFILE_CANCEL_PICTURE camera id %d",
1027              hw->getCameraId());
1028     hw->lockAPI();
1029     qcamera_api_result_t apiResult;
1030     ret = hw->processAPI(QCAMERA_SM_EVT_CANCEL_PICTURE, NULL);
1031     if (ret == NO_ERROR) {
1032         hw->waitAPIResult(QCAMERA_SM_EVT_CANCEL_PICTURE, &apiResult);
1033         ret = apiResult.status;
1034     }
1035     hw->unlockAPI();
1036     LOGI("[KPI Perf]: X camera id %d ret = %d", hw->getCameraId(), ret);
1037 
1038     return ret;
1039 }
1040 
1041 /*===========================================================================
1042  * FUNCTION   : set_parameters
1043  *
1044  * DESCRIPTION: set camera parameters
1045  *
1046  * PARAMETERS :
1047  *   @device  : ptr to camera device struct
1048  *   @parms   : string of packed parameters
1049  *
1050  * RETURN     : int32_t type of status
1051  *              NO_ERROR  -- success
1052  *              none-zero failure code
1053  *==========================================================================*/
set_parameters(struct camera_device * device,const char * parms)1054 int QCamera2HardwareInterface::set_parameters(struct camera_device *device,
1055                                               const char *parms)
1056 {
1057     ATRACE_CALL();
1058     int ret = NO_ERROR;
1059     QCamera2HardwareInterface *hw =
1060         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1061     if (!hw) {
1062         LOGE("NULL camera device");
1063         return BAD_VALUE;
1064     }
1065     LOGD("E camera id %d", hw->getCameraId());
1066     hw->lockAPI();
1067     qcamera_api_result_t apiResult;
1068     ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS, (void *)parms);
1069     if (ret == NO_ERROR) {
1070         hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS, &apiResult);
1071         ret = apiResult.status;
1072     }
1073 
1074     // Give HWI control to restart (if necessary) after set params
1075     // in single camera mode. In dual-cam mode, this control belongs to muxer.
1076     if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
1077         if ((ret == NO_ERROR) && hw->getNeedRestart()) {
1078             LOGD("stopping after param change");
1079             ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_STOP, NULL);
1080             if (ret == NO_ERROR) {
1081                 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_STOP, &apiResult);
1082                 ret = apiResult.status;
1083             }
1084         }
1085 
1086         if (ret == NO_ERROR) {
1087             LOGD("committing param change");
1088             ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, NULL);
1089             if (ret == NO_ERROR) {
1090                 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, &apiResult);
1091                 ret = apiResult.status;
1092             }
1093         }
1094 
1095         if ((ret == NO_ERROR) && hw->getNeedRestart()) {
1096             LOGD("restarting after param change");
1097             ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_RESTART, NULL);
1098             if (ret == NO_ERROR) {
1099                 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_RESTART, &apiResult);
1100                 ret = apiResult.status;
1101             }
1102         }
1103     }
1104 
1105     hw->unlockAPI();
1106     LOGD("X camera id %d ret %d", hw->getCameraId(), ret);
1107 
1108     return ret;
1109 }
1110 
1111 /*===========================================================================
1112  * FUNCTION   : stop_after_set_params
1113  *
1114  * DESCRIPTION: stop after a set param call, if necessary
1115  *
1116  * PARAMETERS :
1117  *   @device  : ptr to camera device struct
1118  *
1119  * RETURN     : int32_t type of status
1120  *              NO_ERROR  -- success
1121  *              none-zero failure code
1122  *==========================================================================*/
stop_after_set_params(struct camera_device * device)1123 int QCamera2HardwareInterface::stop_after_set_params(struct camera_device *device)
1124 {
1125     ATRACE_CALL();
1126     int ret = NO_ERROR;
1127     QCamera2HardwareInterface *hw =
1128         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1129     if (!hw) {
1130         LOGE("NULL camera device");
1131         return BAD_VALUE;
1132     }
1133     LOGD("E camera id %d", hw->getCameraId());
1134     hw->lockAPI();
1135     qcamera_api_result_t apiResult;
1136 
1137     if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
1138         ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_STOP, NULL);
1139         if (ret == NO_ERROR) {
1140             hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_STOP, &apiResult);
1141             ret = apiResult.status;
1142         }
1143     } else {
1144         LOGE("is not supposed to be called in single-camera mode");
1145         ret = INVALID_OPERATION;
1146     }
1147 
1148     hw->unlockAPI();
1149     LOGD("X camera id %d", hw->getCameraId());
1150 
1151     return ret;
1152 }
1153 
1154 /*===========================================================================
1155  * FUNCTION   : commit_params
1156  *
1157  * DESCRIPTION: commit after a set param call
1158  *
1159  * PARAMETERS :
1160  *   @device  : ptr to camera device struct
1161  *
1162  * RETURN     : int32_t type of status
1163  *              NO_ERROR  -- success
1164  *              none-zero failure code
1165  *==========================================================================*/
commit_params(struct camera_device * device)1166 int QCamera2HardwareInterface::commit_params(struct camera_device *device)
1167 {
1168     ATRACE_CALL();
1169     int ret = NO_ERROR;
1170     QCamera2HardwareInterface *hw =
1171         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1172     if (!hw) {
1173         LOGE("NULL camera device");
1174         return BAD_VALUE;
1175     }
1176     LOGD("E camera id %d", hw->getCameraId());
1177     hw->lockAPI();
1178     qcamera_api_result_t apiResult;
1179 
1180     if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
1181         ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, NULL);
1182         if (ret == NO_ERROR) {
1183             hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, &apiResult);
1184             ret = apiResult.status;
1185         }
1186     } else {
1187         LOGE("is not supposed to be called in single-camera mode");
1188         ret = INVALID_OPERATION;
1189     }
1190 
1191     hw->unlockAPI();
1192     LOGD("X camera id %d", hw->getCameraId());
1193 
1194     return ret;
1195 }
1196 
1197 /*===========================================================================
1198  * FUNCTION   : restart_after_set_params
1199  *
1200  * DESCRIPTION: restart after a set param call, if necessary
1201  *
1202  * PARAMETERS :
1203  *   @device  : ptr to camera device struct
1204  *
1205  * RETURN     : int32_t type of status
1206  *              NO_ERROR  -- success
1207  *              none-zero failure code
1208  *==========================================================================*/
restart_after_set_params(struct camera_device * device)1209 int QCamera2HardwareInterface::restart_after_set_params(struct camera_device *device)
1210 {
1211     ATRACE_CALL();
1212     int ret = NO_ERROR;
1213     QCamera2HardwareInterface *hw =
1214         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1215     if (!hw) {
1216         LOGE("NULL camera device");
1217         return BAD_VALUE;
1218     }
1219     LOGD("E camera id %d", hw->getCameraId());
1220     hw->lockAPI();
1221     qcamera_api_result_t apiResult;
1222 
1223     if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
1224         ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_RESTART, NULL);
1225         if (ret == NO_ERROR) {
1226             hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_RESTART, &apiResult);
1227             ret = apiResult.status;
1228         }
1229     } else {
1230         LOGE("is not supposed to be called in single-camera mode");
1231         ret = INVALID_OPERATION;
1232     }
1233 
1234     hw->unlockAPI();
1235     LOGD("X camera id %d", hw->getCameraId());
1236     return ret;
1237 }
1238 
1239 /*===========================================================================
1240  * FUNCTION   : get_parameters
1241  *
1242  * DESCRIPTION: query camera parameters
1243  *
1244  * PARAMETERS :
1245  *   @device  : ptr to camera device struct
1246  *
1247  * RETURN     : packed parameters in a string
1248  *==========================================================================*/
get_parameters(struct camera_device * device)1249 char* QCamera2HardwareInterface::get_parameters(struct camera_device *device)
1250 {
1251     ATRACE_CALL();
1252     char *ret = NULL;
1253     QCamera2HardwareInterface *hw =
1254         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1255     if (!hw) {
1256         LOGE("NULL camera device");
1257         return NULL;
1258     }
1259     LOGD("E camera id %d", hw->getCameraId());
1260     hw->lockAPI();
1261     qcamera_api_result_t apiResult;
1262     int32_t rc = hw->processAPI(QCAMERA_SM_EVT_GET_PARAMS, NULL);
1263     if (rc == NO_ERROR) {
1264         hw->waitAPIResult(QCAMERA_SM_EVT_GET_PARAMS, &apiResult);
1265         ret = apiResult.params;
1266     }
1267     hw->unlockAPI();
1268     LOGD("E camera id %d", hw->getCameraId());
1269 
1270     return ret;
1271 }
1272 
1273 /*===========================================================================
1274  * FUNCTION   : put_parameters
1275  *
1276  * DESCRIPTION: return camera parameters string back to HAL
1277  *
1278  * PARAMETERS :
1279  *   @device  : ptr to camera device struct
1280  *   @parm    : ptr to parameter string to be returned
1281  *
1282  * RETURN     : none
1283  *==========================================================================*/
put_parameters(struct camera_device * device,char * parm)1284 void QCamera2HardwareInterface::put_parameters(struct camera_device *device,
1285                                                char *parm)
1286 {
1287     ATRACE_CALL();
1288     QCamera2HardwareInterface *hw =
1289         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1290     if (!hw) {
1291         LOGE("NULL camera device");
1292         return;
1293     }
1294     LOGD("E camera id %d", hw->getCameraId());
1295     hw->lockAPI();
1296     qcamera_api_result_t apiResult;
1297     int32_t ret = hw->processAPI(QCAMERA_SM_EVT_PUT_PARAMS, (void *)parm);
1298     if (ret == NO_ERROR) {
1299         hw->waitAPIResult(QCAMERA_SM_EVT_PUT_PARAMS, &apiResult);
1300     }
1301     hw->unlockAPI();
1302     LOGD("E camera id %d", hw->getCameraId());
1303 }
1304 
1305 /*===========================================================================
1306  * FUNCTION   : send_command
1307  *
1308  * DESCRIPTION: command to be executed
1309  *
1310  * PARAMETERS :
1311  *   @device  : ptr to camera device struct
1312  *   @cmd     : cmd to be executed
1313  *   @arg1    : ptr to optional argument1
1314  *   @arg2    : ptr to optional argument2
1315  *
1316  * RETURN     : int32_t type of status
1317  *              NO_ERROR  -- success
1318  *              none-zero failure code
1319  *==========================================================================*/
send_command(struct camera_device * device,int32_t cmd,int32_t arg1,int32_t arg2)1320 int QCamera2HardwareInterface::send_command(struct camera_device *device,
1321                                             int32_t cmd,
1322                                             int32_t arg1,
1323                                             int32_t arg2)
1324 {
1325     ATRACE_CALL();
1326     int ret = NO_ERROR;
1327     QCamera2HardwareInterface *hw =
1328         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1329     if (!hw) {
1330         LOGE("NULL camera device");
1331         return BAD_VALUE;
1332     }
1333     LOGD("E camera id %d", hw->getCameraId());
1334 
1335     qcamera_sm_evt_command_payload_t payload;
1336     memset(&payload, 0, sizeof(qcamera_sm_evt_command_payload_t));
1337     payload.cmd = cmd;
1338     payload.arg1 = arg1;
1339     payload.arg2 = arg2;
1340     hw->lockAPI();
1341     qcamera_api_result_t apiResult;
1342     ret = hw->processAPI(QCAMERA_SM_EVT_SEND_COMMAND, (void *)&payload);
1343     if (ret == NO_ERROR) {
1344         hw->waitAPIResult(QCAMERA_SM_EVT_SEND_COMMAND, &apiResult);
1345         ret = apiResult.status;
1346     }
1347     hw->unlockAPI();
1348     LOGD("E camera id %d", hw->getCameraId());
1349 
1350     return ret;
1351 }
1352 
1353 /*===========================================================================
1354  * FUNCTION   : send_command_restart
1355  *
1356  * DESCRIPTION: restart if necessary after a send_command
1357  *
1358  * PARAMETERS :
1359  *   @device  : ptr to camera device struct
1360  *   @cmd     : cmd to be executed
1361  *   @arg1    : ptr to optional argument1
1362  *   @arg2    : ptr to optional argument2
1363  *
1364  * RETURN     : int32_t type of status
1365  *              NO_ERROR  -- success
1366  *              none-zero failure code
1367  *==========================================================================*/
send_command_restart(struct camera_device * device,int32_t cmd,int32_t arg1,int32_t arg2)1368 int QCamera2HardwareInterface::send_command_restart(struct camera_device *device,
1369         int32_t cmd,
1370         int32_t arg1,
1371         int32_t arg2)
1372 {
1373     ATRACE_CALL();
1374     int ret = NO_ERROR;
1375     QCamera2HardwareInterface *hw =
1376             reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1377     if (!hw) {
1378         LOGE("NULL camera device");
1379         return BAD_VALUE;
1380     }
1381 
1382     qcamera_sm_evt_command_payload_t payload;
1383     memset(&payload, 0, sizeof(qcamera_sm_evt_command_payload_t));
1384     payload.cmd = cmd;
1385     payload.arg1 = arg1;
1386     payload.arg2 = arg2;
1387     hw->lockAPI();
1388     qcamera_api_result_t apiResult;
1389     ret = hw->processAPI(QCAMERA_SM_EVT_SEND_COMMAND_RESTART, (void *)&payload);
1390     if (ret == NO_ERROR) {
1391         hw->waitAPIResult(QCAMERA_SM_EVT_SEND_COMMAND_RESTART, &apiResult);
1392         ret = apiResult.status;
1393     }
1394     hw->unlockAPI();
1395     LOGD("E camera id %d", hw->getCameraId());
1396 
1397     return ret;
1398 }
1399 
1400 /*===========================================================================
1401  * FUNCTION   : release
1402  *
1403  * DESCRIPTION: release camera resource
1404  *
1405  * PARAMETERS :
1406  *   @device  : ptr to camera device struct
1407  *
1408  * RETURN     : none
1409  *==========================================================================*/
release(struct camera_device * device)1410 void QCamera2HardwareInterface::release(struct camera_device *device)
1411 {
1412     ATRACE_CALL();
1413     QCamera2HardwareInterface *hw =
1414         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1415     if (!hw) {
1416         LOGE("NULL camera device");
1417         return;
1418     }
1419     LOGD("E camera id %d", hw->getCameraId());
1420     hw->lockAPI();
1421     qcamera_api_result_t apiResult;
1422     int32_t ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE, NULL);
1423     if (ret == NO_ERROR) {
1424         hw->waitAPIResult(QCAMERA_SM_EVT_RELEASE, &apiResult);
1425     }
1426     hw->unlockAPI();
1427     LOGD("E camera id %d", hw->getCameraId());
1428 }
1429 
1430 /*===========================================================================
1431  * FUNCTION   : dump
1432  *
1433  * DESCRIPTION: dump camera status
1434  *
1435  * PARAMETERS :
1436  *   @device  : ptr to camera device struct
1437  *   @fd      : fd for status to be dumped to
1438  *
1439  * RETURN     : int32_t type of status
1440  *              NO_ERROR  -- success
1441  *              none-zero failure code
1442  *==========================================================================*/
dump(struct camera_device * device,int fd)1443 int QCamera2HardwareInterface::dump(struct camera_device *device, int fd)
1444 {
1445     int ret = NO_ERROR;
1446 
1447     //Log level property is read when "adb shell dumpsys media.camera" is
1448     //called so that the log level can be controlled without restarting
1449     //media server
1450     getLogLevel();
1451     QCamera2HardwareInterface *hw =
1452         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1453     if (!hw) {
1454         LOGE("NULL camera device");
1455         return BAD_VALUE;
1456     }
1457     LOGD("E camera id %d", hw->getCameraId());
1458     hw->lockAPI();
1459     qcamera_api_result_t apiResult;
1460     ret = hw->processAPI(QCAMERA_SM_EVT_DUMP, (void *)&fd);
1461     if (ret == NO_ERROR) {
1462         hw->waitAPIResult(QCAMERA_SM_EVT_DUMP, &apiResult);
1463         ret = apiResult.status;
1464     }
1465     hw->unlockAPI();
1466     LOGD("E camera id %d", hw->getCameraId());
1467 
1468     return ret;
1469 }
1470 
1471 /*===========================================================================
1472  * FUNCTION   : close_camera_device
1473  *
1474  * DESCRIPTION: close camera device
1475  *
1476  * PARAMETERS :
1477  *   @device  : ptr to camera device struct
1478  *
1479  * RETURN     : int32_t type of status
1480  *              NO_ERROR  -- success
1481  *              none-zero failure code
1482  *==========================================================================*/
close_camera_device(hw_device_t * hw_dev)1483 int QCamera2HardwareInterface::close_camera_device(hw_device_t *hw_dev)
1484 {
1485     KPI_ATRACE_CALL();
1486     int ret = NO_ERROR;
1487 
1488     QCamera2HardwareInterface *hw =
1489         reinterpret_cast<QCamera2HardwareInterface *>(
1490             reinterpret_cast<camera_device_t *>(hw_dev)->priv);
1491     if (!hw) {
1492         LOGE("NULL camera device");
1493         return BAD_VALUE;
1494     }
1495     LOGI("[KPI Perf]: E camera id %d", hw->getCameraId());
1496     delete hw;
1497     LOGI("[KPI Perf]: X");
1498     return ret;
1499 }
1500 
1501 /*===========================================================================
1502  * FUNCTION   : register_face_image
1503  *
1504  * DESCRIPTION: register a face image into imaging lib for face authenticatio/
1505  *              face recognition
1506  *
1507  * PARAMETERS :
1508  *   @device  : ptr to camera device struct
1509  *   @img_ptr : ptr to image buffer
1510  *   @config  : ptr to config about input image, i.e., format, dimension, and etc.
1511  *
1512  * RETURN     : >=0 unique ID of face registerd.
1513  *              <0  failure.
1514  *==========================================================================*/
register_face_image(struct camera_device * device,void * img_ptr,cam_pp_offline_src_config_t * config)1515 int QCamera2HardwareInterface::register_face_image(struct camera_device *device,
1516                                                    void *img_ptr,
1517                                                    cam_pp_offline_src_config_t *config)
1518 {
1519     ATRACE_CALL();
1520     int ret = NO_ERROR;
1521     QCamera2HardwareInterface *hw =
1522         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1523     if (!hw) {
1524         LOGE("NULL camera device");
1525         return BAD_VALUE;
1526     }
1527     LOGD("E camera id %d", hw->getCameraId());
1528     qcamera_sm_evt_reg_face_payload_t payload;
1529     memset(&payload, 0, sizeof(qcamera_sm_evt_reg_face_payload_t));
1530     payload.img_ptr = img_ptr;
1531     payload.config = config;
1532     hw->lockAPI();
1533     qcamera_api_result_t apiResult;
1534     ret = hw->processAPI(QCAMERA_SM_EVT_REG_FACE_IMAGE, (void *)&payload);
1535     if (ret == NO_ERROR) {
1536         hw->waitAPIResult(QCAMERA_SM_EVT_REG_FACE_IMAGE, &apiResult);
1537         ret = apiResult.handle;
1538     }
1539     hw->unlockAPI();
1540     LOGD("E camera id %d", hw->getCameraId());
1541 
1542     return ret;
1543 }
1544 
1545 /*===========================================================================
1546  * FUNCTION   : prepare_snapshot
1547  *
1548  * DESCRIPTION: prepares hardware for snapshot
1549  *
1550  * PARAMETERS :
1551  *   @device  : ptr to camera device struct
1552  *
1553  * RETURN     : int32_t type of status
1554  *              NO_ERROR  -- success
1555  *              none-zero failure code
1556  *==========================================================================*/
prepare_snapshot(struct camera_device * device)1557 int QCamera2HardwareInterface::prepare_snapshot(struct camera_device *device)
1558 {
1559     ATRACE_CALL();
1560     int ret = NO_ERROR;
1561     QCamera2HardwareInterface *hw =
1562         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1563     if (!hw) {
1564         LOGE("NULL camera device");
1565         return BAD_VALUE;
1566     }
1567     if (hw->isLongshotEnabled() && hw->mPrepSnapRun == true) {
1568         // For longshot mode, we prepare snapshot only once
1569         LOGH("prepare snapshot only once ");
1570         return NO_ERROR;
1571     }
1572     LOGH("[KPI Perf]: E PROFILE_PREPARE_SNAPSHOT camera id %d",
1573              hw->getCameraId());
1574     hw->lockAPI();
1575     qcamera_api_result_t apiResult;
1576 
1577     /* Prepare snapshot in case LED needs to be flashed */
1578     if (hw->mFlashNeeded || hw->mParameters.isChromaFlashEnabled()) {
1579         /* Prepare snapshot in case LED needs to be flashed */
1580         ret = hw->processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL);
1581         if (ret == NO_ERROR) {
1582           hw->waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, &apiResult);
1583             ret = apiResult.status;
1584         }
1585         hw->mPrepSnapRun = true;
1586     }
1587     hw->unlockAPI();
1588     LOGH("[KPI Perf]: X, ret: %d", ret);
1589     return ret;
1590 }
1591 
1592 /*===========================================================================
1593  * FUNCTION   : QCamera2HardwareInterface
1594  *
1595  * DESCRIPTION: constructor of QCamera2HardwareInterface
1596  *
1597  * PARAMETERS :
1598  *   @cameraId  : camera ID
1599  *
1600  * RETURN     : none
1601  *==========================================================================*/
QCamera2HardwareInterface(uint32_t cameraId)1602 QCamera2HardwareInterface::QCamera2HardwareInterface(uint32_t cameraId)
1603     : mCameraId(cameraId),
1604       mCameraHandle(NULL),
1605       mCameraOpened(false),
1606       m_bRelCamCalibValid(false),
1607       mPreviewWindow(NULL),
1608       mMsgEnabled(0),
1609       mStoreMetaDataInFrame(0),
1610       mJpegCb(NULL),
1611       mCallbackCookie(NULL),
1612       mJpegCallbackCookie(NULL),
1613       m_bMpoEnabled(TRUE),
1614       m_stateMachine(this),
1615       m_smThreadActive(true),
1616       m_postprocessor(this),
1617       m_thermalAdapter(QCameraThermalAdapter::getInstance()),
1618       m_cbNotifier(this),
1619       m_bPreviewStarted(false),
1620       m_bRecordStarted(false),
1621       m_currentFocusState(CAM_AF_STATE_INACTIVE),
1622       mDumpFrmCnt(0U),
1623       mDumpSkipCnt(0U),
1624       mThermalLevel(QCAMERA_THERMAL_NO_ADJUSTMENT),
1625       mActiveAF(false),
1626       m_HDRSceneEnabled(false),
1627       mLongshotEnabled(false),
1628       mLiveSnapshotThread(0),
1629       mIntPicThread(0),
1630       mFlashNeeded(false),
1631       mDeviceRotation(0U),
1632       mCaptureRotation(0U),
1633       mJpegExifRotation(0U),
1634       mUseJpegExifRotation(false),
1635       mIs3ALocked(false),
1636       mPrepSnapRun(false),
1637       mZoomLevel(0),
1638       mPreviewRestartNeeded(false),
1639       mVFrameCount(0),
1640       mVLastFrameCount(0),
1641       mVLastFpsTime(0),
1642       mVFps(0),
1643       mPFrameCount(0),
1644       mPLastFrameCount(0),
1645       mPLastFpsTime(0),
1646       mPFps(0),
1647       mInstantAecFrameCount(0),
1648       m_bIntJpegEvtPending(false),
1649       m_bIntRawEvtPending(false),
1650       mReprocJob(0),
1651       mJpegJob(0),
1652       mMetadataAllocJob(0),
1653       mInitPProcJob(0),
1654       mParamAllocJob(0),
1655       mParamInitJob(0),
1656       mOutputCount(0),
1657       mInputCount(0),
1658       mAdvancedCaptureConfigured(false),
1659       mHDRBracketingEnabled(false),
1660       mNumPreviewFaces(-1),
1661       mJpegClientHandle(0),
1662       mJpegHandleOwner(false),
1663       mMetadataMem(NULL),
1664       mCACDoneReceived(false),
1665       m_bNeedRestart(false)
1666 {
1667 #ifdef TARGET_TS_MAKEUP
1668     memset(&mFaceRect, -1, sizeof(mFaceRect));
1669 #endif
1670     getLogLevel();
1671     ATRACE_CALL();
1672     mCameraDevice.common.tag = HARDWARE_DEVICE_TAG;
1673     mCameraDevice.common.version = HARDWARE_DEVICE_API_VERSION(1, 0);
1674     mCameraDevice.common.close = close_camera_device;
1675     mCameraDevice.ops = &mCameraOps;
1676     mCameraDevice.priv = this;
1677 
1678     pthread_mutex_init(&m_lock, NULL);
1679     pthread_cond_init(&m_cond, NULL);
1680 
1681     m_apiResultList = NULL;
1682 
1683     pthread_mutex_init(&m_evtLock, NULL);
1684     pthread_cond_init(&m_evtCond, NULL);
1685     memset(&m_evtResult, 0, sizeof(qcamera_api_result_t));
1686 
1687 
1688     pthread_mutex_init(&m_int_lock, NULL);
1689     pthread_cond_init(&m_int_cond, NULL);
1690 
1691     memset(m_channels, 0, sizeof(m_channels));
1692 
1693     memset(&mExifParams, 0, sizeof(mm_jpeg_exif_params_t));
1694 
1695     memset(m_BackendFileName, 0, QCAMERA_MAX_FILEPATH_LENGTH);
1696 
1697     memset(mDefOngoingJobs, 0, sizeof(mDefOngoingJobs));
1698     memset(&mJpegMetadata, 0, sizeof(mJpegMetadata));
1699     memset(&mJpegHandle, 0, sizeof(mJpegHandle));
1700     memset(&mJpegMpoHandle, 0, sizeof(mJpegMpoHandle));
1701 
1702     mDeferredWorkThread.launch(deferredWorkRoutine, this);
1703     mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_START_DATA_PROC, FALSE, FALSE);
1704     m_perfLock.lock_init();
1705 
1706     pthread_mutex_init(&mGrallocLock, NULL);
1707     mEnqueuedBuffers = 0;
1708     mFrameSkipStart = 0;
1709     mFrameSkipEnd = 0;
1710     mLastPreviewFrameID = 0;
1711 
1712     //Load and read GPU library.
1713     lib_surface_utils = NULL;
1714     LINK_get_surface_pixel_alignment = NULL;
1715     mSurfaceStridePadding = CAM_PAD_TO_32;
1716     lib_surface_utils = dlopen("libadreno_utils.so", RTLD_NOW);
1717     if (lib_surface_utils) {
1718         *(void **)&LINK_get_surface_pixel_alignment =
1719                 dlsym(lib_surface_utils, "get_gpu_pixel_alignment");
1720          if (LINK_get_surface_pixel_alignment) {
1721              mSurfaceStridePadding = LINK_get_surface_pixel_alignment();
1722          }
1723          dlclose(lib_surface_utils);
1724     }
1725 }
1726 
1727 /*===========================================================================
1728  * FUNCTION   : ~QCamera2HardwareInterface
1729  *
1730  * DESCRIPTION: destructor of QCamera2HardwareInterface
1731  *
1732  * PARAMETERS : none
1733  *
1734  * RETURN     : none
1735  *==========================================================================*/
~QCamera2HardwareInterface()1736 QCamera2HardwareInterface::~QCamera2HardwareInterface()
1737 {
1738     LOGH("E");
1739 
1740     mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_STOP_DATA_PROC, TRUE, TRUE);
1741     mDeferredWorkThread.exit();
1742 
1743     if (mMetadataMem != NULL) {
1744         delete mMetadataMem;
1745         mMetadataMem = NULL;
1746     }
1747 
1748     m_perfLock.lock_acq();
1749     lockAPI();
1750     m_smThreadActive = false;
1751     unlockAPI();
1752     m_stateMachine.releaseThread();
1753     closeCamera();
1754     m_perfLock.lock_rel();
1755     m_perfLock.lock_deinit();
1756     pthread_mutex_destroy(&m_lock);
1757     pthread_cond_destroy(&m_cond);
1758     pthread_mutex_destroy(&m_evtLock);
1759     pthread_cond_destroy(&m_evtCond);
1760     pthread_mutex_destroy(&m_int_lock);
1761     pthread_cond_destroy(&m_int_cond);
1762     pthread_mutex_destroy(&mGrallocLock);
1763     LOGH("X");
1764 }
1765 
1766 /*===========================================================================
1767  * FUNCTION   : deferPPInit
1768  *
1769  * DESCRIPTION: Queue postproc init task to deferred thread
1770  *
1771  * PARAMETERS : none
1772  *
1773  * RETURN     : uint32_t job id of pproc init job
1774  *              0  -- failure
1775  *==========================================================================*/
deferPPInit()1776 uint32_t QCamera2HardwareInterface::deferPPInit()
1777 {
1778     // init pproc
1779     DeferWorkArgs args;
1780     DeferPProcInitArgs pprocInitArgs;
1781 
1782     memset(&args, 0, sizeof(DeferWorkArgs));
1783     memset(&pprocInitArgs, 0, sizeof(DeferPProcInitArgs));
1784 
1785     pprocInitArgs.jpeg_cb = jpegEvtHandle;
1786     pprocInitArgs.user_data = this;
1787     args.pprocInitArgs = pprocInitArgs;
1788 
1789     return queueDeferredWork(CMD_DEF_PPROC_INIT,
1790             args);
1791 }
1792 
1793 /*===========================================================================
1794  * FUNCTION   : openCamera
1795  *
1796  * DESCRIPTION: open camera
1797  *
1798  * PARAMETERS :
1799  *   @hw_device  : double ptr for camera device struct
1800  *
1801  * RETURN     : int32_t type of status
1802  *              NO_ERROR  -- success
1803  *              none-zero failure code
1804  *==========================================================================*/
openCamera(struct hw_device_t ** hw_device)1805 int QCamera2HardwareInterface::openCamera(struct hw_device_t **hw_device)
1806 {
1807     KPI_ATRACE_CALL();
1808     int rc = NO_ERROR;
1809     if (mCameraOpened) {
1810         *hw_device = NULL;
1811         LOGE("Permission Denied");
1812         return PERMISSION_DENIED;
1813     }
1814     LOGI("[KPI Perf]: E PROFILE_OPEN_CAMERA camera id %d",
1815             mCameraId);
1816     m_perfLock.lock_acq_timed(CAMERA_OPEN_PERF_TIME_OUT);
1817     rc = openCamera();
1818     if (rc == NO_ERROR){
1819         *hw_device = &mCameraDevice.common;
1820         if (m_thermalAdapter.init(this) != 0) {
1821           LOGW("Init thermal adapter failed");
1822         }
1823     }
1824     else
1825         *hw_device = NULL;
1826 
1827     LOGI("[KPI Perf]: X PROFILE_OPEN_CAMERA camera id %d, rc: %d",
1828             mCameraId, rc);
1829 
1830     return rc;
1831 }
1832 
1833 /*===========================================================================
1834  * FUNCTION   : openCamera
1835  *
1836  * DESCRIPTION: open camera
1837  *
1838  * PARAMETERS : none
1839  *
1840  * RETURN     : int32_t type of status
1841  *              NO_ERROR  -- success
1842  *              none-zero failure code
1843  *==========================================================================*/
openCamera()1844 int QCamera2HardwareInterface::openCamera()
1845 {
1846     int32_t rc = NO_ERROR;
1847     char value[PROPERTY_VALUE_MAX];
1848 
1849     if (mCameraHandle) {
1850         LOGE("Failure: Camera already opened");
1851         return ALREADY_EXISTS;
1852     }
1853 
1854     rc = QCameraFlash::getInstance().reserveFlashForCamera(mCameraId);
1855     if (rc < 0) {
1856         LOGE("Failed to reserve flash for camera id: %d",
1857                 mCameraId);
1858         return UNKNOWN_ERROR;
1859     }
1860 
1861     // alloc param buffer
1862     DeferWorkArgs args;
1863     memset(&args, 0, sizeof(args));
1864     mParamAllocJob = queueDeferredWork(CMD_DEF_PARAM_ALLOC, args);
1865     if (mParamAllocJob == 0) {
1866         LOGE("Failed queueing PARAM_ALLOC job");
1867         return -ENOMEM;
1868     }
1869 
1870     if (gCamCapability[mCameraId] != NULL) {
1871         // allocate metadata buffers
1872         DeferWorkArgs args;
1873         DeferMetadataAllocArgs metadataAllocArgs;
1874 
1875         memset(&args, 0, sizeof(args));
1876         memset(&metadataAllocArgs, 0, sizeof(metadataAllocArgs));
1877 
1878         uint32_t padding =
1879                 gCamCapability[mCameraId]->padding_info.plane_padding;
1880         metadataAllocArgs.size = PAD_TO_SIZE(sizeof(metadata_buffer_t),
1881                 padding);
1882         metadataAllocArgs.bufferCnt = CAMERA_MIN_METADATA_BUFFERS;
1883         args.metadataAllocArgs = metadataAllocArgs;
1884 
1885         mMetadataAllocJob = queueDeferredWork(CMD_DEF_METADATA_ALLOC, args);
1886         if (mMetadataAllocJob == 0) {
1887             LOGE("Failed to allocate metadata buffer");
1888             rc = -ENOMEM;
1889             goto error_exit1;
1890         }
1891 
1892         rc = camera_open((uint8_t)mCameraId, &mCameraHandle);
1893         if (rc) {
1894             LOGE("camera_open failed. rc = %d, mCameraHandle = %p",
1895                      rc, mCameraHandle);
1896             goto error_exit2;
1897         }
1898 
1899         mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle,
1900                 camEvtHandle,
1901                 (void *) this);
1902     } else {
1903         LOGH("Capabilities not inited, initializing now.");
1904 
1905         rc = camera_open((uint8_t)mCameraId, &mCameraHandle);
1906         if (rc) {
1907             LOGE("camera_open failed. rc = %d, mCameraHandle = %p",
1908                      rc, mCameraHandle);
1909             goto error_exit2;
1910         }
1911 
1912         if(NO_ERROR != initCapabilities(mCameraId,mCameraHandle)) {
1913             LOGE("initCapabilities failed.");
1914             rc = UNKNOWN_ERROR;
1915             goto error_exit3;
1916         }
1917 
1918         mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle,
1919                 camEvtHandle,
1920                 (void *) this);
1921     }
1922 
1923     // Init params in the background
1924     // 1. It's safe to queue init job, even if alloc job is not yet complete.
1925     // It will be queued to the same thread, so the alloc is guaranteed to
1926     // finish first.
1927     // 2. However, it is not safe to begin param init until after camera is
1928     // open. That is why we wait until after camera open completes to schedule
1929     // this task.
1930     memset(&args, 0, sizeof(args));
1931     mParamInitJob = queueDeferredWork(CMD_DEF_PARAM_INIT, args);
1932     if (mParamInitJob == 0) {
1933         LOGE("Failed queuing PARAM_INIT job");
1934         rc = -ENOMEM;
1935         goto error_exit3;
1936     }
1937 
1938     mCameraOpened = true;
1939 
1940     //Notify display HAL that a camera session is active.
1941     //But avoid calling the same during bootup because camera service might open/close
1942     //cameras at boot time during its initialization and display service will also internally
1943     //wait for camera service to initialize first while calling this display API, resulting in a
1944     //deadlock situation. Since boot time camera open/close calls are made only to fetch
1945     //capabilities, no need of this display bw optimization.
1946     //Use "service.bootanim.exit" property to know boot status.
1947     property_get("service.bootanim.exit", value, "0");
1948     if (atoi(value) == 1) {
1949         pthread_mutex_lock(&gCamLock);
1950         if (gNumCameraSessions++ == 0) {
1951             setCameraLaunchStatus(true);
1952         }
1953         pthread_mutex_unlock(&gCamLock);
1954     }
1955 
1956     return NO_ERROR;
1957 
1958 error_exit3:
1959     if(mJpegClientHandle) {
1960         deinitJpegHandle();
1961     }
1962     mCameraHandle->ops->close_camera(mCameraHandle->camera_handle);
1963     mCameraHandle = NULL;
1964 error_exit2:
1965     waitDeferredWork(mMetadataAllocJob);
1966 error_exit1:
1967     waitDeferredWork(mParamAllocJob);
1968     return rc;
1969 
1970 }
1971 
1972 /*===========================================================================
1973  * FUNCTION   : bundleRelatedCameras
1974  *
1975  * DESCRIPTION: bundle cameras to enable syncing of cameras
1976  *
1977  * PARAMETERS :
1978  *   @sync        :indicates whether syncing is On or Off
1979  *   @sessionid  :session id for other camera session
1980  *
1981  * RETURN     : int32_t type of status
1982  *              NO_ERROR  -- success
1983  *              none-zero failure code
1984  *==========================================================================*/
bundleRelatedCameras(bool syncOn,uint32_t sessionid)1985 int QCamera2HardwareInterface::bundleRelatedCameras(bool syncOn,
1986             uint32_t sessionid)
1987 {
1988     LOGD("bundleRelatedCameras sync %d with sessionid %d",
1989             syncOn, sessionid);
1990 
1991     int32_t rc = mParameters.bundleRelatedCameras(syncOn, sessionid);
1992     if (rc != NO_ERROR) {
1993         LOGE("bundleRelatedCameras failed %d", rc);
1994         return rc;
1995     }
1996     return rc;
1997 }
1998 
1999 /*===========================================================================
2000  * FUNCTION   : getCameraSessionId
2001  *
2002  * DESCRIPTION: gets the backend session Id of this HWI instance
2003  *
2004  * PARAMETERS :
2005  *   @sessionid  : pointer to the output session id
2006  *
2007  * RETURN     : int32_t type of status
2008  *              NO_ERROR  -- success
2009  *              none-zero failure code
2010  *==========================================================================*/
getCameraSessionId(uint32_t * session_id)2011 int QCamera2HardwareInterface::getCameraSessionId(uint32_t* session_id)
2012 {
2013     int32_t rc = NO_ERROR;
2014 
2015     if(session_id != NULL) {
2016         rc = mCameraHandle->ops->get_session_id(mCameraHandle->camera_handle,
2017                 session_id);
2018         LOGD("Getting Camera Session Id %d", *session_id);
2019     } else {
2020         LOGE("Session Id is Null");
2021         return UNKNOWN_ERROR;
2022     }
2023     return rc;
2024 }
2025 
2026 /*===========================================================================
2027  * FUNCTION   : getRelatedCamSyncInfo
2028  *
2029  * DESCRIPTION:returns the related cam sync info for this HWI instance
2030  *
2031  * PARAMETERS :none
2032  *
2033  * RETURN     : const pointer to cam_sync_related_sensors_event_info_t
2034  *==========================================================================*/
2035 const cam_sync_related_sensors_event_info_t*
getRelatedCamSyncInfo(void)2036         QCamera2HardwareInterface::getRelatedCamSyncInfo(void)
2037 {
2038     return mParameters.getRelatedCamSyncInfo();
2039 }
2040 
2041 /*===========================================================================
2042  * FUNCTION   : setRelatedCamSyncInfo
2043  *
2044  * DESCRIPTION:sets the related cam sync info for this HWI instance
2045  *
2046  * PARAMETERS :
2047  *   @info  : ptr to related cam info parameters
2048  *
2049  * RETURN     : int32_t type of status
2050  *              NO_ERROR  -- success
2051  *              none-zero failure code
2052  *==========================================================================*/
setRelatedCamSyncInfo(cam_sync_related_sensors_event_info_t * info)2053 int32_t QCamera2HardwareInterface::setRelatedCamSyncInfo(
2054         cam_sync_related_sensors_event_info_t* info)
2055 {
2056     if(info) {
2057         return mParameters.setRelatedCamSyncInfo(info);
2058     } else {
2059         return BAD_TYPE;
2060     }
2061 }
2062 
2063 /*===========================================================================
2064  * FUNCTION   : getMpoComposition
2065  *
2066  * DESCRIPTION:function to retrieve whether Mpo composition should be enabled
2067  *                    or not
2068  *
2069  * PARAMETERS :none
2070  *
2071  * RETURN     : bool indicates whether mpo composition is enabled or not
2072  *==========================================================================*/
getMpoComposition(void)2073 bool QCamera2HardwareInterface::getMpoComposition(void)
2074 {
2075     LOGH("MpoComposition:%d ", m_bMpoEnabled);
2076     return m_bMpoEnabled;
2077 }
2078 
2079 /*===========================================================================
2080  * FUNCTION   : setMpoComposition
2081  *
2082  * DESCRIPTION:set if Mpo composition should be enabled for this HWI instance
2083  *
2084  * PARAMETERS :
2085  *   @enable  : indicates whether Mpo composition enabled or not
2086  *
2087  * RETURN     : int32_t type of status
2088  *              NO_ERROR  -- success
2089  *              none-zero failure code
2090  *==========================================================================*/
setMpoComposition(bool enable)2091 int32_t QCamera2HardwareInterface::setMpoComposition(bool enable)
2092 {
2093     // By default set Mpo composition to disable
2094     m_bMpoEnabled = false;
2095 
2096     // Enable Mpo composition only if
2097     // 1) frame sync is ON between two cameras and
2098     // 2) any advanced features are not enabled (AOST features) and
2099     // 3) not in recording mode (for liveshot case)
2100     // 4) flash is not needed
2101     if ((getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) &&
2102             !mParameters.isAdvCamFeaturesEnabled() &&
2103             !mParameters.getRecordingHintValue() &&
2104             !mFlashNeeded &&
2105             !isLongshotEnabled()) {
2106         m_bMpoEnabled = enable;
2107         LOGH("MpoComposition:%d ", m_bMpoEnabled);
2108         return NO_ERROR;
2109     } else {
2110         return BAD_TYPE;
2111     }
2112 }
2113 
2114 /*===========================================================================
2115  * FUNCTION   : getRecordingHintValue
2116  *
2117  * DESCRIPTION:function to retrieve recording hint value
2118  *
2119  * PARAMETERS :none
2120  *
2121  * RETURN     : bool indicates whether recording hint is enabled or not
2122  *==========================================================================*/
getRecordingHintValue(void)2123 bool QCamera2HardwareInterface::getRecordingHintValue(void)
2124 {
2125     return mParameters.getRecordingHintValue();
2126 }
2127 
2128 /*===========================================================================
2129  * FUNCTION   : setRecordingHintValue
2130  *
2131  * DESCRIPTION:set recording hint value
2132  *
2133  * PARAMETERS :
2134  *   @enable  : video hint value
2135  *
2136  * RETURN     : int32_t type of status
2137  *              NO_ERROR  -- success
2138  *              none-zero failure code
2139  *==========================================================================*/
setRecordingHintValue(int32_t value)2140 int32_t QCamera2HardwareInterface::setRecordingHintValue(int32_t value)
2141 {
2142     return mParameters.updateRecordingHintValue(value);
2143 }
2144 
2145 /*===========================================================================
2146  * FUNCTION   : closeCamera
2147  *
2148  * DESCRIPTION: close camera
2149  *
2150  * PARAMETERS : none
2151  *
2152  * RETURN     : int32_t type of status
2153  *              NO_ERROR  -- success
2154  *              none-zero failure code
2155  *==========================================================================*/
closeCamera()2156 int QCamera2HardwareInterface::closeCamera()
2157 {
2158     int rc = NO_ERROR;
2159     int i;
2160     char value[PROPERTY_VALUE_MAX];
2161     LOGI("E");
2162     if (!mCameraOpened) {
2163         return NO_ERROR;
2164     }
2165     LOGI("[KPI Perf]: E PROFILE_CLOSE_CAMERA camera id %d",
2166              mCameraId);
2167 
2168     // set open flag to false
2169     mCameraOpened = false;
2170 
2171     // Reset Stream config info
2172     mParameters.setStreamConfigure(false, false, true);
2173 
2174     // deinit Parameters
2175     mParameters.deinit();
2176 
2177     // exit notifier
2178     m_cbNotifier.exit();
2179 
2180     // stop and deinit postprocessor
2181     waitDeferredWork(mReprocJob);
2182     // Close the JPEG session
2183     waitDeferredWork(mJpegJob);
2184     m_postprocessor.stop();
2185     deinitJpegHandle();
2186     m_postprocessor.deinit();
2187     mInitPProcJob = 0; // reset job id, so pproc can be reinited later
2188 
2189     m_thermalAdapter.deinit();
2190 
2191     // delete all channels if not already deleted
2192     for (i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
2193         if (m_channels[i] != NULL) {
2194             m_channels[i]->stop();
2195             delete m_channels[i];
2196             m_channels[i] = NULL;
2197         }
2198     }
2199 
2200     //free all pending api results here
2201     if(m_apiResultList != NULL) {
2202         api_result_list *apiResultList = m_apiResultList;
2203         api_result_list *apiResultListNext;
2204         while (apiResultList != NULL) {
2205             apiResultListNext = apiResultList->next;
2206             free(apiResultList);
2207             apiResultList = apiResultListNext;
2208         }
2209     }
2210 
2211     rc = mCameraHandle->ops->close_camera(mCameraHandle->camera_handle);
2212     mCameraHandle = NULL;
2213 
2214     //Notify display HAL that there is no active camera session
2215     //but avoid calling the same during bootup. Refer to openCamera
2216     //for more details.
2217     property_get("service.bootanim.exit", value, "0");
2218     if (atoi(value) == 1) {
2219         pthread_mutex_lock(&gCamLock);
2220         if (--gNumCameraSessions == 0) {
2221             setCameraLaunchStatus(false);
2222         }
2223         pthread_mutex_unlock(&gCamLock);
2224     }
2225 
2226     if (mExifParams.debug_params) {
2227         free(mExifParams.debug_params);
2228         mExifParams.debug_params = NULL;
2229     }
2230 
2231     if (QCameraFlash::getInstance().releaseFlashFromCamera(mCameraId) != 0) {
2232         LOGD("Failed to release flash for camera id: %d",
2233                 mCameraId);
2234     }
2235 
2236     LOGI("[KPI Perf]: X PROFILE_CLOSE_CAMERA camera id %d, rc: %d",
2237          mCameraId, rc);
2238 
2239     return rc;
2240 }
2241 
2242 #define DATA_PTR(MEM_OBJ,INDEX) MEM_OBJ->getPtr( INDEX )
2243 
2244 /*===========================================================================
2245  * FUNCTION   : initCapabilities
2246  *
2247  * DESCRIPTION: initialize camera capabilities in static data struct
2248  *
2249  * PARAMETERS :
2250  *   @cameraId  : camera Id
2251  *
2252  * RETURN     : int32_t type of status
2253  *              NO_ERROR  -- success
2254  *              none-zero failure code
2255  *==========================================================================*/
initCapabilities(uint32_t cameraId,mm_camera_vtbl_t * cameraHandle)2256 int QCamera2HardwareInterface::initCapabilities(uint32_t cameraId,
2257         mm_camera_vtbl_t *cameraHandle)
2258 {
2259     ATRACE_CALL();
2260     int rc = NO_ERROR;
2261     QCameraHeapMemory *capabilityHeap = NULL;
2262 
2263     /* Allocate memory for capability buffer */
2264     capabilityHeap = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
2265     rc = capabilityHeap->allocate(1, sizeof(cam_capability_t), NON_SECURE);
2266     if(rc != OK) {
2267         LOGE("No memory for cappability");
2268         goto allocate_failed;
2269     }
2270 
2271     /* Map memory for capability buffer */
2272     memset(DATA_PTR(capabilityHeap,0), 0, sizeof(cam_capability_t));
2273 
2274     cam_buf_map_type_list bufMapList;
2275     rc = QCameraBufferMaps::makeSingletonBufMapList(
2276             CAM_MAPPING_BUF_TYPE_CAPABILITY,
2277             0 /*stream id*/, 0 /*buffer index*/, -1 /*plane index*/,
2278             0 /*cookie*/, capabilityHeap->getFd(0), sizeof(cam_capability_t),
2279             bufMapList);
2280 
2281     if (rc == NO_ERROR) {
2282         rc = cameraHandle->ops->map_bufs(cameraHandle->camera_handle,
2283                 &bufMapList);
2284     }
2285 
2286     if(rc < 0) {
2287         LOGE("failed to map capability buffer");
2288         goto map_failed;
2289     }
2290 
2291     /* Query Capability */
2292     rc = cameraHandle->ops->query_capability(cameraHandle->camera_handle);
2293     if(rc < 0) {
2294         LOGE("failed to query capability");
2295         goto query_failed;
2296     }
2297     gCamCapability[cameraId] =
2298             (cam_capability_t *)malloc(sizeof(cam_capability_t));
2299 
2300     if (!gCamCapability[cameraId]) {
2301         LOGE("out of memory");
2302         goto query_failed;
2303     }
2304     memcpy(gCamCapability[cameraId], DATA_PTR(capabilityHeap,0),
2305                                         sizeof(cam_capability_t));
2306     gCamCapability[cameraId]->analysis_padding_info.offset_info.offset_x = 0;
2307     gCamCapability[cameraId]->analysis_padding_info.offset_info.offset_y = 0;
2308 
2309     rc = NO_ERROR;
2310 
2311 query_failed:
2312     cameraHandle->ops->unmap_buf(cameraHandle->camera_handle,
2313                             CAM_MAPPING_BUF_TYPE_CAPABILITY);
2314 map_failed:
2315     capabilityHeap->deallocate();
2316     delete capabilityHeap;
2317 allocate_failed:
2318     return rc;
2319 }
2320 
2321 /*===========================================================================
2322  * FUNCTION   : getCapabilities
2323  *
2324  * DESCRIPTION: query camera capabilities
2325  *
2326  * PARAMETERS :
2327  *   @cameraId  : camera Id
2328  *   @info      : camera info struct to be filled in with camera capabilities
2329  *
2330  * RETURN     : int type of status
2331  *              NO_ERROR  -- success
2332  *              none-zero failure code
2333  *==========================================================================*/
getCapabilities(uint32_t cameraId,struct camera_info * info,cam_sync_type_t * p_cam_type)2334 int QCamera2HardwareInterface::getCapabilities(uint32_t cameraId,
2335         struct camera_info *info, cam_sync_type_t *p_cam_type)
2336 {
2337     ATRACE_CALL();
2338     int rc = NO_ERROR;
2339     struct  camera_info *p_info = NULL;
2340     pthread_mutex_lock(&gCamLock);
2341     p_info = get_cam_info(cameraId, p_cam_type);
2342     p_info->device_version = CAMERA_DEVICE_API_VERSION_1_0;
2343     p_info->static_camera_characteristics = NULL;
2344     memcpy(info, p_info, sizeof (struct camera_info));
2345     pthread_mutex_unlock(&gCamLock);
2346     return rc;
2347 }
2348 
2349 /*===========================================================================
2350  * FUNCTION   : getCamHalCapabilities
2351  *
2352  * DESCRIPTION: get the HAL capabilities structure
2353  *
2354  * PARAMETERS :
2355  *   @cameraId  : camera Id
2356  *
2357  * RETURN     : capability structure of respective camera
2358  *
2359  *==========================================================================*/
getCamHalCapabilities()2360 cam_capability_t* QCamera2HardwareInterface::getCamHalCapabilities()
2361 {
2362     return gCamCapability[mCameraId];
2363 }
2364 
2365 /*===========================================================================
2366  * FUNCTION   : getBufNumRequired
2367  *
2368  * DESCRIPTION: return number of stream buffers needed for given stream type
2369  *
2370  * PARAMETERS :
2371  *   @stream_type  : type of stream
2372  *
2373  * RETURN     : number of buffers needed
2374  *==========================================================================*/
getBufNumRequired(cam_stream_type_t stream_type)2375 uint8_t QCamera2HardwareInterface::getBufNumRequired(cam_stream_type_t stream_type)
2376 {
2377     int bufferCnt = 0;
2378     int minCaptureBuffers = mParameters.getNumOfSnapshots();
2379     char value[PROPERTY_VALUE_MAX];
2380     bool raw_yuv = false;
2381     int persist_cnt = 0;
2382 
2383     int zslQBuffers = mParameters.getZSLQueueDepth();
2384 
2385     int minCircularBufNum = mParameters.getMaxUnmatchedFramesInQueue() +
2386                             CAMERA_MIN_JPEG_ENCODING_BUFFERS;
2387 
2388     int maxStreamBuf = minCaptureBuffers + mParameters.getMaxUnmatchedFramesInQueue() +
2389                        mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2390                        mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2391                        mParameters.getNumOfExtraBuffersForImageProc() +
2392                        EXTRA_ZSL_PREVIEW_STREAM_BUF;
2393 
2394     int minUndequeCount = 0;
2395     if (!isNoDisplayMode()) {
2396         if(mPreviewWindow != NULL) {
2397             if (mPreviewWindow->get_min_undequeued_buffer_count(mPreviewWindow,&minUndequeCount)
2398                 != 0) {
2399                 LOGW("get_min_undequeued_buffer_count  failed");
2400                 //TODO: hardcoded because MIN_UNDEQUEUED_BUFFERS not defined
2401                 //minUndequeCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS;
2402                 minUndequeCount = MIN_UNDEQUEUED_BUFFERS;
2403             }
2404         } else {
2405             //preview window might not be set at this point. So, query directly
2406             //from BufferQueue implementation of gralloc buffers.
2407             //minUndequeCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS;
2408             //hardcoded because MIN_UNDEQUEUED_BUFFERS not defined. REVISIT
2409             minUndequeCount = MIN_UNDEQUEUED_BUFFERS;
2410         }
2411         if (minUndequeCount != MIN_UNDEQUEUED_BUFFERS) {
2412             // minUndequeCount from valid preview window != hardcoded MIN_UNDEQUEUED_BUFFERS
2413             // and so change the MACRO as per minUndequeCount
2414             LOGW("WARNING : minUndequeCount(%d) != hardcoded value(%d)",
2415                      minUndequeCount, MIN_UNDEQUEUED_BUFFERS);
2416         }
2417     }
2418 
2419     LOGD("minCaptureBuffers = %d zslQBuffers = %d minCircularBufNum = %d"
2420             "maxStreamBuf = %d minUndequeCount = %d",
2421             minCaptureBuffers, zslQBuffers, minCircularBufNum,
2422             maxStreamBuf, minUndequeCount);
2423     // Get buffer count for the particular stream type
2424     switch (stream_type) {
2425     case CAM_STREAM_TYPE_PREVIEW:
2426         {
2427             if (mParameters.isZSLMode()) {
2428                 // We need to add two extra streming buffers to add
2429                 // flexibility in forming matched super buf in ZSL queue.
2430                 // with number being 'zslQBuffers + minCircularBufNum'
2431                 // we see preview buffers sometimes get dropped at CPP
2432                 // and super buf is not forming in ZSL Q for long time.
2433 
2434                 bufferCnt = zslQBuffers + minCircularBufNum +
2435                         mParameters.getNumOfExtraBuffersForImageProc() +
2436                         mParameters.getNumOfExtraBuffersForPreview() +
2437                         mParameters.getNumOfExtraHDRInBufsIfNeeded();
2438             } else {
2439                 bufferCnt = CAMERA_MIN_STREAMING_BUFFERS +
2440                         mParameters.getMaxUnmatchedFramesInQueue() +
2441                         mParameters.getNumOfExtraBuffersForPreview();
2442             }
2443             // ISP allocates native preview buffers and so reducing same from HAL allocation
2444             if (bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS )
2445                 bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS;
2446 
2447             if (mParameters.getRecordingHintValue() == true)
2448                 bufferCnt += EXTRA_ZSL_PREVIEW_STREAM_BUF;
2449 
2450             // Add the display minUndequeCount count on top of camera requirement
2451             bufferCnt += minUndequeCount;
2452 
2453             property_get("persist.camera.preview_yuv", value, "0");
2454             persist_cnt = atoi(value);
2455             if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM)
2456                     && (bufferCnt < persist_cnt)) {
2457                 bufferCnt = persist_cnt;
2458             }
2459         }
2460         break;
2461     case CAM_STREAM_TYPE_POSTVIEW:
2462         {
2463             bufferCnt = minCaptureBuffers +
2464                         mParameters.getMaxUnmatchedFramesInQueue() +
2465                         mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2466                         mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2467                         mParameters.getNumOfExtraBuffersForImageProc();
2468 
2469             if (bufferCnt > maxStreamBuf) {
2470                 bufferCnt = maxStreamBuf;
2471             }
2472             bufferCnt += minUndequeCount;
2473         }
2474         break;
2475     case CAM_STREAM_TYPE_SNAPSHOT:
2476         {
2477             if (mParameters.isZSLMode() || mLongshotEnabled) {
2478                 if ((minCaptureBuffers == 1 || mParameters.isUbiRefocus()) &&
2479                         !mLongshotEnabled) {
2480                     // Single ZSL snapshot case
2481                     bufferCnt = zslQBuffers + CAMERA_MIN_STREAMING_BUFFERS +
2482                             mParameters.getNumOfExtraBuffersForImageProc();
2483                 }
2484                 else {
2485                     // ZSL Burst or Longshot case
2486                     bufferCnt = zslQBuffers + minCircularBufNum +
2487                             mParameters.getNumOfExtraBuffersForImageProc();
2488                 }
2489                 if (getSensorType() == CAM_SENSOR_YUV && bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS) {
2490                     //ISP allocates native buffers in YUV case
2491                     bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS;
2492                 }
2493             } else {
2494                 bufferCnt = minCaptureBuffers +
2495                             mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2496                             mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2497                             mParameters.getNumOfExtraBuffersForImageProc();
2498 
2499                 if (bufferCnt > maxStreamBuf) {
2500                     bufferCnt = maxStreamBuf;
2501                 }
2502             }
2503         }
2504         break;
2505     case CAM_STREAM_TYPE_RAW:
2506         property_get("persist.camera.raw_yuv", value, "0");
2507         raw_yuv = atoi(value) > 0 ? true : false;
2508 
2509         if (isRdiMode() || raw_yuv) {
2510             bufferCnt = zslQBuffers + minCircularBufNum;
2511         } else if (mParameters.isZSLMode()) {
2512             bufferCnt = zslQBuffers + minCircularBufNum;
2513             if (getSensorType() == CAM_SENSOR_YUV && bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS) {
2514                 //ISP allocates native buffers in YUV case
2515                 bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS;
2516             }
2517 
2518         } else {
2519             bufferCnt = minCaptureBuffers +
2520                         mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2521                         mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2522                         mParameters.getNumOfExtraBuffersForImageProc();
2523 
2524             if (bufferCnt > maxStreamBuf) {
2525                 bufferCnt = maxStreamBuf;
2526             }
2527         }
2528 
2529         property_get("persist.camera.preview_raw", value, "0");
2530         persist_cnt = atoi(value);
2531         if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM)
2532                 && (bufferCnt < persist_cnt)) {
2533             bufferCnt = persist_cnt;
2534         }
2535         property_get("persist.camera.video_raw", value, "0");
2536         persist_cnt = atoi(value);
2537         if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM)
2538                 && (bufferCnt < persist_cnt)) {
2539             bufferCnt = persist_cnt;
2540         }
2541 
2542         break;
2543     case CAM_STREAM_TYPE_VIDEO:
2544         {
2545             if (mParameters.getBufBatchCount()) {
2546                 //Video Buffer in case of HFR or camera batching..
2547                 bufferCnt = CAMERA_MIN_CAMERA_BATCH_BUFFERS;
2548             } else if (mParameters.getVideoBatchSize()) {
2549                 //Video Buffer count only for HAL to HAL batching.
2550                 bufferCnt = (CAMERA_MIN_VIDEO_BATCH_BUFFERS
2551                         * mParameters.getVideoBatchSize());
2552                 if (bufferCnt < CAMERA_MIN_VIDEO_BUFFERS) {
2553                     bufferCnt = CAMERA_MIN_VIDEO_BUFFERS;
2554                 }
2555             } else {
2556                 // No batching enabled.
2557                 bufferCnt = CAMERA_MIN_VIDEO_BUFFERS;
2558             }
2559 
2560             bufferCnt += mParameters.getNumOfExtraBuffersForVideo();
2561             //if its 4K encoding usecase, then add extra buffer
2562             cam_dimension_t dim;
2563             mParameters.getStreamDimension(CAM_STREAM_TYPE_VIDEO, dim);
2564             if (is4k2kResolution(&dim)) {
2565                  //get additional buffer count
2566                  property_get("vidc.enc.dcvs.extra-buff-count", value, "0");
2567                  bufferCnt += atoi(value);
2568             }
2569         }
2570         break;
2571     case CAM_STREAM_TYPE_METADATA:
2572         {
2573             if (mParameters.isZSLMode()) {
2574                 // MetaData buffers should be >= (Preview buffers-minUndequeCount)
2575                 bufferCnt = zslQBuffers + minCircularBufNum +
2576                             mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2577                             mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2578                             mParameters.getNumOfExtraBuffersForImageProc() +
2579                             EXTRA_ZSL_PREVIEW_STREAM_BUF;
2580             } else {
2581                 bufferCnt = minCaptureBuffers +
2582                             mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2583                             mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2584                             mParameters.getMaxUnmatchedFramesInQueue() +
2585                             CAMERA_MIN_STREAMING_BUFFERS +
2586                             mParameters.getNumOfExtraBuffersForImageProc();
2587 
2588                 if (bufferCnt > zslQBuffers + minCircularBufNum) {
2589                     bufferCnt = zslQBuffers + minCircularBufNum;
2590                 }
2591             }
2592             if (CAMERA_MIN_METADATA_BUFFERS > bufferCnt) {
2593                 bufferCnt = CAMERA_MIN_METADATA_BUFFERS;
2594             }
2595         }
2596         break;
2597     case CAM_STREAM_TYPE_OFFLINE_PROC:
2598         {
2599             bufferCnt = minCaptureBuffers;
2600             // One of the ubifocus buffers is miscellaneous buffer
2601             if (mParameters.isUbiRefocus()) {
2602                 bufferCnt -= 1;
2603             }
2604             if (mLongshotEnabled) {
2605                 bufferCnt = mParameters.getLongshotStages();
2606             }
2607         }
2608         break;
2609     case CAM_STREAM_TYPE_CALLBACK:
2610         bufferCnt = CAMERA_MIN_CALLBACK_BUFFERS;
2611         break;
2612     case CAM_STREAM_TYPE_ANALYSIS:
2613     case CAM_STREAM_TYPE_DEFAULT:
2614     case CAM_STREAM_TYPE_MAX:
2615     default:
2616         bufferCnt = 0;
2617         break;
2618     }
2619 
2620     LOGH("Buffer count = %d for stream type = %d", bufferCnt, stream_type);
2621     if (CAM_MAX_NUM_BUFS_PER_STREAM < bufferCnt) {
2622         LOGW("Buffer count %d for stream type %d exceeds limit %d",
2623                  bufferCnt, stream_type, CAM_MAX_NUM_BUFS_PER_STREAM);
2624         return CAM_MAX_NUM_BUFS_PER_STREAM;
2625     }
2626 
2627     return (uint8_t)bufferCnt;
2628 }
2629 
2630 /*===========================================================================
2631  * FUNCTION   : allocateStreamBuf
2632  *
2633  * DESCRIPTION: alocate stream buffers
2634  *
2635  * PARAMETERS :
2636  *   @stream_type  : type of stream
2637  *   @size         : size of buffer
2638  *   @stride       : stride of buffer
2639  *   @scanline     : scanline of buffer
2640  *   @bufferCnt    : [IN/OUT] minimum num of buffers to be allocated.
2641  *                   could be modified during allocation if more buffers needed
2642  *
2643  * RETURN     : ptr to a memory obj that holds stream buffers.
2644  *              NULL if failed
2645  *==========================================================================*/
allocateStreamBuf(cam_stream_type_t stream_type,size_t size,int stride,int scanline,uint8_t & bufferCnt)2646 QCameraMemory *QCamera2HardwareInterface::allocateStreamBuf(
2647         cam_stream_type_t stream_type, size_t size, int stride, int scanline,
2648         uint8_t &bufferCnt)
2649 {
2650     int rc = NO_ERROR;
2651     QCameraMemory *mem = NULL;
2652     bool bCachedMem = QCAMERA_ION_USE_CACHE;
2653     bool bPoolMem = false;
2654     char value[PROPERTY_VALUE_MAX];
2655     property_get("persist.camera.mem.usepool", value, "1");
2656     if (atoi(value) == 1) {
2657         bPoolMem = true;
2658     }
2659 
2660     // Allocate stream buffer memory object
2661     switch (stream_type) {
2662     case CAM_STREAM_TYPE_PREVIEW:
2663         {
2664             if (isNoDisplayMode()) {
2665                 mem = new QCameraStreamMemory(mGetMemory,
2666                         bCachedMem,
2667                         (bPoolMem) ? &m_memoryPool : NULL,
2668                         stream_type);
2669             } else {
2670                 cam_dimension_t dim;
2671                 int minFPS, maxFPS;
2672                 QCameraGrallocMemory *grallocMemory =
2673                     new QCameraGrallocMemory(mGetMemory);
2674 
2675                 mParameters.getStreamDimension(stream_type, dim);
2676                 /* we are interested only in maxfps here */
2677                 mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
2678                 int usage = 0;
2679                 if(mParameters.isUBWCEnabled()) {
2680                     cam_format_t fmt;
2681                     mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW,fmt);
2682                     if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
2683                         usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC ;
2684                     }
2685                 }
2686                 if (grallocMemory) {
2687                     grallocMemory->setMappable(
2688                             CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS);
2689                     grallocMemory->setWindowInfo(mPreviewWindow,
2690                             dim.width,dim.height, stride, scanline,
2691                             mParameters.getPreviewHalPixelFormat(),
2692                             maxFPS, usage);
2693                     pthread_mutex_lock(&mGrallocLock);
2694                     if (bufferCnt > CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS) {
2695                         mEnqueuedBuffers = (bufferCnt -
2696                                 CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS);
2697                     } else {
2698                         mEnqueuedBuffers = 0;
2699                     }
2700                     pthread_mutex_unlock(&mGrallocLock);
2701                 }
2702                 mem = grallocMemory;
2703             }
2704         }
2705         break;
2706     case CAM_STREAM_TYPE_POSTVIEW:
2707         {
2708             if (isNoDisplayMode() || isPreviewRestartEnabled()) {
2709                 mem = new QCameraStreamMemory(mGetMemory, bCachedMem);
2710             } else {
2711                 cam_dimension_t dim;
2712                 int minFPS, maxFPS;
2713                 QCameraGrallocMemory *grallocMemory =
2714                         new QCameraGrallocMemory(mGetMemory);
2715 
2716                 mParameters.getStreamDimension(stream_type, dim);
2717                 /* we are interested only in maxfps here */
2718                 mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
2719                 if (grallocMemory) {
2720                     grallocMemory->setWindowInfo(mPreviewWindow, dim.width,
2721                             dim.height, stride, scanline,
2722                             mParameters.getPreviewHalPixelFormat(), maxFPS);
2723                 }
2724                 mem = grallocMemory;
2725             }
2726         }
2727         break;
2728     case CAM_STREAM_TYPE_ANALYSIS:
2729     case CAM_STREAM_TYPE_SNAPSHOT:
2730     case CAM_STREAM_TYPE_RAW:
2731     case CAM_STREAM_TYPE_OFFLINE_PROC:
2732         mem = new QCameraStreamMemory(mGetMemory,
2733                 bCachedMem,
2734                 (bPoolMem) ? &m_memoryPool : NULL,
2735                 stream_type);
2736         break;
2737     case CAM_STREAM_TYPE_METADATA:
2738         {
2739             if (mMetadataMem == NULL) {
2740                 mem = new QCameraMetadataStreamMemory(QCAMERA_ION_USE_CACHE);
2741             } else {
2742                 mem = mMetadataMem;
2743                 mMetadataMem = NULL;
2744 
2745                 int32_t numAdditionalBuffers = bufferCnt - mem->getCnt();
2746                 if (numAdditionalBuffers > 0) {
2747                     rc = mem->allocateMore(numAdditionalBuffers, size);
2748                     if (rc != NO_ERROR) {
2749                         LOGE("Failed to allocate additional buffers, "
2750                                 "but attempting to proceed.");
2751                     }
2752                 }
2753                 bufferCnt = mem->getCnt();
2754                 // The memory is already allocated  and initialized, so
2755                 // simply return here.
2756                 return mem;
2757             }
2758         }
2759         break;
2760     case CAM_STREAM_TYPE_VIDEO:
2761         {
2762             //Use uncached allocation by default
2763             if (mParameters.isVideoBuffersCached() || mParameters.isSeeMoreEnabled() ||
2764                     mParameters.isHighQualityNoiseReductionMode()) {
2765                 bCachedMem = QCAMERA_ION_USE_CACHE;
2766             }
2767             else {
2768                 bCachedMem = QCAMERA_ION_USE_NOCACHE;
2769             }
2770 
2771             QCameraVideoMemory *videoMemory = NULL;
2772             if (mParameters.getVideoBatchSize()) {
2773                 videoMemory = new QCameraVideoMemory(
2774                         mGetMemory, FALSE, QCAMERA_MEM_TYPE_BATCH);
2775                 if (videoMemory == NULL) {
2776                     LOGE("Out of memory for video batching obj");
2777                     return NULL;
2778                 }
2779                 /*
2780                 *   numFDs = BATCH size
2781                 *  numInts = 5  // OFFSET, SIZE, USAGE, TIMESTAMP, FORMAT
2782                 */
2783                 rc = videoMemory->allocateMeta(
2784                         CAMERA_MIN_VIDEO_BATCH_BUFFERS,
2785                         mParameters.getVideoBatchSize(),
2786                         VIDEO_METADATA_NUM_INTS);
2787                 if (rc < 0) {
2788                     delete videoMemory;
2789                     return NULL;
2790                 }
2791             } else {
2792                 videoMemory =
2793                         new QCameraVideoMemory(mGetMemory, bCachedMem);
2794                 if (videoMemory == NULL) {
2795                     LOGE("Out of memory for video obj");
2796                     return NULL;
2797                 }
2798             }
2799 
2800             int usage = 0;
2801             cam_format_t fmt;
2802             mParameters.getStreamFormat(CAM_STREAM_TYPE_VIDEO,fmt);
2803             if (mParameters.isUBWCEnabled() && (fmt == CAM_FORMAT_YUV_420_NV12_UBWC)) {
2804                 usage = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
2805             }
2806             videoMemory->setVideoInfo(usage, fmt);
2807             mem = videoMemory;
2808         }
2809         break;
2810     case CAM_STREAM_TYPE_CALLBACK:
2811         mem = new QCameraStreamMemory(mGetMemory,
2812                 bCachedMem,
2813                 (bPoolMem) ? &m_memoryPool : NULL,
2814                 stream_type);
2815         break;
2816     case CAM_STREAM_TYPE_DEFAULT:
2817     case CAM_STREAM_TYPE_MAX:
2818     default:
2819         break;
2820     }
2821     if (!mem) {
2822         return NULL;
2823     }
2824 
2825     if (bufferCnt > 0) {
2826         if (mParameters.isSecureMode() &&
2827             (stream_type == CAM_STREAM_TYPE_RAW) &&
2828             (mParameters.isRdiMode())) {
2829             LOGD("Allocating %d secure buffers of size %d ", bufferCnt, size);
2830             rc = mem->allocate(bufferCnt, size, SECURE);
2831         } else {
2832             rc = mem->allocate(bufferCnt, size, NON_SECURE);
2833         }
2834         if (rc < 0) {
2835             delete mem;
2836             return NULL;
2837         }
2838         bufferCnt = mem->getCnt();
2839     }
2840     LOGH("rc = %d type = %d count = %d size = %d cache = %d, pool = %d",
2841             rc, stream_type, bufferCnt, size, bCachedMem, bPoolMem);
2842     return mem;
2843 }
2844 
2845 /*===========================================================================
2846  * FUNCTION   : allocateMoreStreamBuf
2847  *
2848  * DESCRIPTION: alocate more stream buffers from the memory object
2849  *
2850  * PARAMETERS :
2851  *   @mem_obj      : memory object ptr
2852  *   @size         : size of buffer
2853  *   @bufferCnt    : [IN/OUT] additional number of buffers to be allocated.
2854  *                   output will be the number of total buffers
2855  *
2856  * RETURN     : int32_t type of status
2857  *              NO_ERROR  -- success
2858  *              none-zero failure code
2859  *==========================================================================*/
allocateMoreStreamBuf(QCameraMemory * mem_obj,size_t size,uint8_t & bufferCnt)2860 int32_t QCamera2HardwareInterface::allocateMoreStreamBuf(
2861         QCameraMemory *mem_obj, size_t size, uint8_t &bufferCnt)
2862 {
2863     int rc = NO_ERROR;
2864 
2865     if (bufferCnt > 0) {
2866         rc = mem_obj->allocateMore(bufferCnt, size);
2867         bufferCnt = mem_obj->getCnt();
2868     }
2869     return rc;
2870 }
2871 
2872 /*===========================================================================
2873  * FUNCTION   : allocateMiscBuf
2874  *
2875  * DESCRIPTION: alocate miscellaneous buffer
2876  *
2877  * PARAMETERS :
2878  *   @streamInfo  : stream info
2879  *
2880  * RETURN     : ptr to a memory obj that holds stream info buffer.
2881  *              NULL if failed
2882  *==========================================================================*/
allocateMiscBuf(cam_stream_info_t * streamInfo)2883 QCameraHeapMemory *QCamera2HardwareInterface::allocateMiscBuf(
2884         cam_stream_info_t *streamInfo)
2885 {
2886     int rc = NO_ERROR;
2887     uint8_t bufNum = 0;
2888     size_t bufSize = 0;
2889     QCameraHeapMemory *miscBuf = NULL;
2890     uint32_t feature_mask =
2891             streamInfo->reprocess_config.pp_feature_config.feature_mask;
2892 
2893     switch (streamInfo->stream_type) {
2894     case CAM_STREAM_TYPE_OFFLINE_PROC:
2895         if (CAM_QCOM_FEATURE_TRUEPORTRAIT & feature_mask) {
2896             bufNum = 1;
2897             bufSize = mParameters.getTPMaxMetaSize();
2898         } else if (CAM_QCOM_FEATURE_REFOCUS & feature_mask) {
2899             bufNum = 1;
2900             bufSize = mParameters.getRefocusMaxMetaSize();
2901         }
2902         break;
2903     default:
2904         break;
2905     }
2906 
2907     if (bufNum && bufSize) {
2908         miscBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
2909 
2910         if (!miscBuf) {
2911             LOGE("Unable to allocate miscBuf object");
2912             return NULL;
2913         }
2914 
2915         rc = miscBuf->allocate(bufNum, bufSize, NON_SECURE);
2916         if (rc < 0) {
2917             LOGE("Failed to allocate misc buffer memory");
2918             delete miscBuf;
2919             return NULL;
2920         }
2921     }
2922 
2923     return miscBuf;
2924 }
2925 
2926 /*===========================================================================
2927  * FUNCTION   : allocateStreamInfoBuf
2928  *
2929  * DESCRIPTION: alocate stream info buffer
2930  *
2931  * PARAMETERS :
2932  *   @stream_type  : type of stream
2933  *
2934  * RETURN     : ptr to a memory obj that holds stream info buffer.
2935  *              NULL if failed
2936  *==========================================================================*/
allocateStreamInfoBuf(cam_stream_type_t stream_type)2937 QCameraHeapMemory *QCamera2HardwareInterface::allocateStreamInfoBuf(
2938         cam_stream_type_t stream_type)
2939 {
2940     int rc = NO_ERROR;
2941     char value[PROPERTY_VALUE_MAX];
2942     bool raw_yuv = false;
2943 
2944     QCameraHeapMemory *streamInfoBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
2945     if (!streamInfoBuf) {
2946         LOGE("allocateStreamInfoBuf: Unable to allocate streamInfo object");
2947         return NULL;
2948     }
2949 
2950     rc = streamInfoBuf->allocate(1, sizeof(cam_stream_info_t), NON_SECURE);
2951     if (rc < 0) {
2952         LOGE("allocateStreamInfoBuf: Failed to allocate stream info memory");
2953         delete streamInfoBuf;
2954         return NULL;
2955     }
2956 
2957     cam_stream_info_t *streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(0);
2958     memset(streamInfo, 0, sizeof(cam_stream_info_t));
2959     streamInfo->stream_type = stream_type;
2960     rc = mParameters.getStreamFormat(stream_type, streamInfo->fmt);
2961     rc = mParameters.getStreamDimension(stream_type, streamInfo->dim);
2962     rc = mParameters.getStreamRotation(stream_type, streamInfo->pp_config, streamInfo->dim);
2963     streamInfo->num_bufs = getBufNumRequired(stream_type);
2964     streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
2965     streamInfo->is_secure = NON_SECURE;
2966 
2967     switch (stream_type) {
2968     case CAM_STREAM_TYPE_SNAPSHOT:
2969         if ((mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) ||
2970             mLongshotEnabled) {
2971             streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
2972         } else {
2973             streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
2974             streamInfo->num_of_burst = (uint8_t)
2975                     (mParameters.getNumOfSnapshots()
2976                         + mParameters.getNumOfExtraHDRInBufsIfNeeded()
2977                         - mParameters.getNumOfExtraHDROutBufsIfNeeded()
2978                         + mParameters.getNumOfExtraBuffersForImageProc());
2979         }
2980         break;
2981     case CAM_STREAM_TYPE_RAW:
2982         property_get("persist.camera.raw_yuv", value, "0");
2983         raw_yuv = atoi(value) > 0 ? true : false;
2984         if ((mParameters.isZSLMode()) || (isRdiMode()) || (raw_yuv)) {
2985             streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
2986         } else {
2987             streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
2988             streamInfo->num_of_burst = mParameters.getNumOfSnapshots();
2989         }
2990         if (mParameters.isSecureMode() && mParameters.isRdiMode()) {
2991             streamInfo->is_secure = SECURE;
2992         } else {
2993             streamInfo->is_secure = NON_SECURE;
2994         }
2995         break;
2996     case CAM_STREAM_TYPE_POSTVIEW:
2997         if (mLongshotEnabled) {
2998             streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
2999         } else {
3000             streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
3001             streamInfo->num_of_burst = (uint8_t)(mParameters.getNumOfSnapshots()
3002                 + mParameters.getNumOfExtraHDRInBufsIfNeeded()
3003                 - mParameters.getNumOfExtraHDROutBufsIfNeeded()
3004                 + mParameters.getNumOfExtraBuffersForImageProc());
3005         }
3006         break;
3007     case CAM_STREAM_TYPE_VIDEO:
3008         streamInfo->dis_enable = mParameters.isDISEnabled();
3009         if (mParameters.getBufBatchCount()) {
3010             //Update stream info structure with batch mode info
3011             streamInfo->streaming_mode = CAM_STREAMING_MODE_BATCH;
3012             streamInfo->user_buf_info.frame_buf_cnt = mParameters.getBufBatchCount();
3013             streamInfo->user_buf_info.size =
3014                     (uint32_t)(sizeof(struct msm_camera_user_buf_cont_t));
3015             cam_fps_range_t pFpsRange;
3016             mParameters.getHfrFps(pFpsRange);
3017             streamInfo->user_buf_info.frameInterval =
3018                     (long)((1000/pFpsRange.video_max_fps) * 1000);
3019             LOGH("Video Batch Count = %d, interval = %d",
3020                     streamInfo->user_buf_info.frame_buf_cnt,
3021                     streamInfo->user_buf_info.frameInterval);
3022         }
3023     case CAM_STREAM_TYPE_PREVIEW:
3024         if (mParameters.getRecordingHintValue()) {
3025             if(mParameters.isDISEnabled()) {
3026                 streamInfo->is_type = mParameters.getISType();
3027             } else {
3028                 streamInfo->is_type = IS_TYPE_NONE;
3029             }
3030         }
3031         if (mParameters.isSecureMode()) {
3032             streamInfo->is_secure = SECURE;
3033         }
3034         break;
3035     case CAM_STREAM_TYPE_ANALYSIS:
3036         streamInfo->noFrameExpected = 1;
3037         break;
3038     default:
3039         break;
3040     }
3041 
3042     // Update feature mask
3043     mParameters.updatePpFeatureMask(stream_type);
3044 
3045     // Get feature mask
3046     mParameters.getStreamPpMask(stream_type, streamInfo->pp_config.feature_mask);
3047 
3048     // Update pp config
3049     if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_FLIP) {
3050         int flipMode = mParameters.getFlipMode(stream_type);
3051         if (flipMode > 0) {
3052             streamInfo->pp_config.flip = (uint32_t)flipMode;
3053         }
3054     }
3055     if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_SHARPNESS) {
3056         streamInfo->pp_config.sharpness = mParameters.getSharpness();
3057     }
3058     if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_EFFECT) {
3059         streamInfo->pp_config.effect = mParameters.getEffectValue();
3060     }
3061 
3062     if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_DENOISE2D) {
3063         streamInfo->pp_config.denoise2d.denoise_enable = 1;
3064         streamInfo->pp_config.denoise2d.process_plates =
3065                 mParameters.getDenoiseProcessPlate(CAM_INTF_PARM_WAVELET_DENOISE);
3066     }
3067 
3068     if (!((needReprocess()) && (CAM_STREAM_TYPE_SNAPSHOT == stream_type ||
3069             CAM_STREAM_TYPE_RAW == stream_type))) {
3070         if (gCamCapability[mCameraId]->qcom_supported_feature_mask &
3071                 CAM_QCOM_FEATURE_CROP)
3072             streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
3073         if (gCamCapability[mCameraId]->qcom_supported_feature_mask &
3074                 CAM_QCOM_FEATURE_SCALE)
3075             streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
3076     }
3077 
3078     LOGH("type %d, fmt %d, dim %dx%d, num_bufs %d mask = 0x%x\n",
3079            stream_type, streamInfo->fmt, streamInfo->dim.width,
3080            streamInfo->dim.height, streamInfo->num_bufs,
3081            streamInfo->pp_config.feature_mask);
3082 
3083     return streamInfoBuf;
3084 }
3085 
3086 /*===========================================================================
3087  * FUNCTION   : allocateStreamUserBuf
3088  *
3089  * DESCRIPTION: allocate user ptr for stream buffers
3090  *
3091  * PARAMETERS :
3092  *   @streamInfo  : stream info structure
3093  *
3094  * RETURN     : ptr to a memory obj that holds stream info buffer.
3095  *                    NULL if failed
3096 
3097  *==========================================================================*/
allocateStreamUserBuf(cam_stream_info_t * streamInfo)3098 QCameraMemory *QCamera2HardwareInterface::allocateStreamUserBuf(
3099         cam_stream_info_t *streamInfo)
3100 {
3101     int rc = NO_ERROR;
3102     QCameraMemory *mem = NULL;
3103     int size = 0;
3104 
3105     if (streamInfo->streaming_mode != CAM_STREAMING_MODE_BATCH) {
3106         LOGE("Stream is not in BATCH mode. Invalid Stream");
3107         return NULL;
3108     }
3109 
3110     // Allocate stream user buffer memory object
3111     switch (streamInfo->stream_type) {
3112     case CAM_STREAM_TYPE_VIDEO: {
3113         QCameraVideoMemory *video_mem = new QCameraVideoMemory(
3114                 mGetMemory, FALSE, QCAMERA_MEM_TYPE_BATCH);
3115         if (video_mem == NULL) {
3116             LOGE("Out of memory for video obj");
3117             return NULL;
3118         }
3119         /*
3120         *   numFDs = BATCH size
3121         *  numInts = 5  // OFFSET, SIZE, USAGE, TIMESTAMP, FORMAT
3122         */
3123         rc = video_mem->allocateMeta(streamInfo->num_bufs,
3124                 mParameters.getBufBatchCount(), VIDEO_METADATA_NUM_INTS);
3125         if (rc < 0) {
3126             LOGE("allocateMeta failed");
3127             delete video_mem;
3128             return NULL;
3129         }
3130         int usage = 0;
3131         cam_format_t fmt;
3132         mParameters.getStreamFormat(CAM_STREAM_TYPE_VIDEO, fmt);
3133         if(mParameters.isUBWCEnabled() && (fmt == CAM_FORMAT_YUV_420_NV12_UBWC)) {
3134             usage = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
3135         }
3136         video_mem->setVideoInfo(usage, fmt);
3137         mem = static_cast<QCameraMemory *>(video_mem);
3138     }
3139     break;
3140 
3141     case CAM_STREAM_TYPE_PREVIEW:
3142     case CAM_STREAM_TYPE_POSTVIEW:
3143     case CAM_STREAM_TYPE_ANALYSIS:
3144     case CAM_STREAM_TYPE_SNAPSHOT:
3145     case CAM_STREAM_TYPE_RAW:
3146     case CAM_STREAM_TYPE_METADATA:
3147     case CAM_STREAM_TYPE_OFFLINE_PROC:
3148     case CAM_STREAM_TYPE_CALLBACK:
3149         LOGE("Stream type Not supported.for BATCH processing");
3150     break;
3151 
3152     case CAM_STREAM_TYPE_DEFAULT:
3153     case CAM_STREAM_TYPE_MAX:
3154     default:
3155         break;
3156     }
3157     if (!mem) {
3158         LOGE("Failed to allocate mem");
3159         return NULL;
3160     }
3161 
3162     /*Size of this buffer will be number of batch buffer */
3163     size = PAD_TO_SIZE((streamInfo->num_bufs * streamInfo->user_buf_info.size),
3164             CAM_PAD_TO_4K);
3165 
3166     LOGH("Allocating BATCH Buffer count = %d", streamInfo->num_bufs);
3167 
3168     if (size > 0) {
3169         // Allocating one buffer for all batch buffers
3170         rc = mem->allocate(1, size, NON_SECURE);
3171         if (rc < 0) {
3172             delete mem;
3173             return NULL;
3174         }
3175     }
3176     return mem;
3177 }
3178 
3179 
3180 /*===========================================================================
3181  * FUNCTION   : waitForDeferredAlloc
3182  *
3183  * DESCRIPTION: Wait for deferred allocation, if applicable
3184  *              (applicable only for metadata buffers so far)
3185  *
3186  * PARAMETERS :
3187  *   @stream_type  : type of stream to (possibly) wait for
3188  *
3189  * RETURN     : None
3190  *==========================================================================*/
waitForDeferredAlloc(cam_stream_type_t stream_type)3191 void QCamera2HardwareInterface::waitForDeferredAlloc(cam_stream_type_t stream_type)
3192 {
3193     if (stream_type == CAM_STREAM_TYPE_METADATA) {
3194         waitDeferredWork(mMetadataAllocJob);
3195     }
3196 }
3197 
3198 
3199 /*===========================================================================
3200  * FUNCTION   : setPreviewWindow
3201  *
3202  * DESCRIPTION: set preview window impl
3203  *
3204  * PARAMETERS :
3205  *   @window  : ptr to window ops table struct
3206  *
3207  * RETURN     : int32_t type of status
3208  *              NO_ERROR  -- success
3209  *              none-zero failure code
3210  *==========================================================================*/
setPreviewWindow(struct preview_stream_ops * window)3211 int QCamera2HardwareInterface::setPreviewWindow(
3212         struct preview_stream_ops *window)
3213 {
3214     mPreviewWindow = window;
3215     return NO_ERROR;
3216 }
3217 
3218 /*===========================================================================
3219  * FUNCTION   : setCallBacks
3220  *
3221  * DESCRIPTION: set callbacks impl
3222  *
3223  * PARAMETERS :
3224  *   @notify_cb  : notify cb
3225  *   @data_cb    : data cb
3226  *   @data_cb_timestamp : data cb with time stamp
3227  *   @get_memory : request memory ops table
3228  *   @user       : user data ptr
3229  *
3230  * RETURN     : int32_t type of status
3231  *              NO_ERROR  -- success
3232  *              none-zero failure code
3233  *==========================================================================*/
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)3234 int QCamera2HardwareInterface::setCallBacks(camera_notify_callback notify_cb,
3235                                             camera_data_callback data_cb,
3236                                             camera_data_timestamp_callback data_cb_timestamp,
3237                                             camera_request_memory get_memory,
3238                                             void *user)
3239 {
3240     mNotifyCb        = notify_cb;
3241     mDataCb          = data_cb;
3242     mDataCbTimestamp = data_cb_timestamp;
3243     mGetMemory       = get_memory;
3244     mCallbackCookie  = user;
3245     m_cbNotifier.setCallbacks(notify_cb, data_cb, data_cb_timestamp, user);
3246     return NO_ERROR;
3247 }
3248 
3249 /*===========================================================================
3250  * FUNCTION   : setJpegCallBacks
3251  *
3252  * DESCRIPTION: set JPEG callbacks impl
3253  *
3254  * PARAMETERS :
3255  *   @jpegCb  : Jpeg callback method
3256  *   @callbackCookie    : callback cookie
3257  *
3258  * RETURN     : int32_t type of status
3259  *              NO_ERROR  -- success
3260  *              none-zero failure code
3261  *==========================================================================*/
setJpegCallBacks(jpeg_data_callback jpegCb,void * callbackCookie)3262 void QCamera2HardwareInterface::setJpegCallBacks(jpeg_data_callback jpegCb,
3263                                             void *callbackCookie)
3264 {
3265     LOGH("camera id %d", getCameraId());
3266     mJpegCb        = jpegCb;
3267     mJpegCallbackCookie  = callbackCookie;
3268     m_cbNotifier.setJpegCallBacks(mJpegCb, mJpegCallbackCookie);
3269 }
3270 
3271 /*===========================================================================
3272  * FUNCTION   : enableMsgType
3273  *
3274  * DESCRIPTION: enable msg type impl
3275  *
3276  * PARAMETERS :
3277  *   @msg_type  : msg type mask to be enabled
3278  *
3279  * RETURN     : int32_t type of status
3280  *              NO_ERROR  -- success
3281  *              none-zero failure code
3282  *==========================================================================*/
enableMsgType(int32_t msg_type)3283 int QCamera2HardwareInterface::enableMsgType(int32_t msg_type)
3284 {
3285     int32_t rc = NO_ERROR;
3286 
3287     if (mParameters.isUBWCEnabled()) {
3288         /*Need Special CALLBACK stream incase application requesting for
3289               Preview callback  in UBWC case*/
3290         if (!(msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) &&
3291                 (msg_type & CAMERA_MSG_PREVIEW_FRAME)) {
3292             if (m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL) {
3293                 rc = startChannel(QCAMERA_CH_TYPE_CALLBACK);
3294                 if (rc != NO_ERROR) {
3295                     LOGE("START Callback Channel failed");
3296                 }
3297             }
3298         }
3299     }
3300     mMsgEnabled |= msg_type;
3301     LOGH("(0x%x) : mMsgEnabled = 0x%x rc = %d", msg_type , mMsgEnabled, rc);
3302     return rc;
3303 }
3304 
3305 /*===========================================================================
3306  * FUNCTION   : disableMsgType
3307  *
3308  * DESCRIPTION: disable msg type impl
3309  *
3310  * PARAMETERS :
3311  *   @msg_type  : msg type mask to be disabled
3312  *
3313  * RETURN     : int32_t type of status
3314  *              NO_ERROR  -- success
3315  *              none-zero failure code
3316  *==========================================================================*/
disableMsgType(int32_t msg_type)3317 int QCamera2HardwareInterface::disableMsgType(int32_t msg_type)
3318 {
3319     int32_t rc = NO_ERROR;
3320 
3321     if (mParameters.isUBWCEnabled()) {
3322         /*STOP CALLBACK STREAM*/
3323         if ((msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) &&
3324                 (msg_type & CAMERA_MSG_PREVIEW_FRAME)) {
3325             if (m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL) {
3326                 rc = stopChannel(QCAMERA_CH_TYPE_CALLBACK);
3327                 if (rc != NO_ERROR) {
3328                     LOGE("STOP Callback Channel failed");
3329                 }
3330             }
3331         }
3332     }
3333     mMsgEnabled &= ~msg_type;
3334     LOGH("(0x%x) : mMsgEnabled = 0x%x rc = %d", msg_type , mMsgEnabled, rc);
3335     return rc;
3336 }
3337 
3338 /*===========================================================================
3339  * FUNCTION   : msgTypeEnabled
3340  *
3341  * DESCRIPTION: impl to determine if certain msg_type is enabled
3342  *
3343  * PARAMETERS :
3344  *   @msg_type  : msg type mask
3345  *
3346  * RETURN     : 0 -- not enabled
3347  *              none 0 -- enabled
3348  *==========================================================================*/
msgTypeEnabled(int32_t msg_type)3349 int QCamera2HardwareInterface::msgTypeEnabled(int32_t msg_type)
3350 {
3351     return (mMsgEnabled & msg_type);
3352 }
3353 
3354 /*===========================================================================
3355  * FUNCTION   : msgTypeEnabledWithLock
3356  *
3357  * DESCRIPTION: impl to determine if certain msg_type is enabled with lock
3358  *
3359  * PARAMETERS :
3360  *   @msg_type  : msg type mask
3361  *
3362  * RETURN     : 0 -- not enabled
3363  *              none 0 -- enabled
3364  *==========================================================================*/
msgTypeEnabledWithLock(int32_t msg_type)3365 int QCamera2HardwareInterface::msgTypeEnabledWithLock(int32_t msg_type)
3366 {
3367     int enabled = 0;
3368     lockAPI();
3369     enabled = mMsgEnabled & msg_type;
3370     unlockAPI();
3371     return enabled;
3372 }
3373 
3374 /*===========================================================================
3375  * FUNCTION   : startPreview
3376  *
3377  * DESCRIPTION: start preview impl
3378  *
3379  * PARAMETERS : none
3380  *
3381  * RETURN     : int32_t type of status
3382  *              NO_ERROR  -- success
3383  *              none-zero failure code
3384  *==========================================================================*/
startPreview()3385 int QCamera2HardwareInterface::startPreview()
3386 {
3387     KPI_ATRACE_CALL();
3388     int32_t rc = NO_ERROR;
3389 
3390     LOGI("E ZSL = %d Recording Hint = %d", mParameters.isZSLMode(),
3391             mParameters.getRecordingHintValue());
3392 
3393     m_perfLock.lock_acq();
3394 
3395     updateThermalLevel((void *)&mThermalLevel);
3396 
3397     setDisplayFrameSkip();
3398 
3399     // start preview stream
3400     if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) {
3401         rc = startChannel(QCAMERA_CH_TYPE_ZSL);
3402     } else {
3403         rc = startChannel(QCAMERA_CH_TYPE_PREVIEW);
3404     }
3405 
3406     if (rc != NO_ERROR) {
3407         LOGE("failed to start channels");
3408         m_perfLock.lock_rel();
3409         return rc;
3410     }
3411 
3412     if ((msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME))
3413             && (m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL)) {
3414         rc = startChannel(QCAMERA_CH_TYPE_CALLBACK);
3415         if (rc != NO_ERROR) {
3416             LOGE("failed to start callback stream");
3417             stopChannel(QCAMERA_CH_TYPE_ZSL);
3418             stopChannel(QCAMERA_CH_TYPE_PREVIEW);
3419             m_perfLock.lock_rel();
3420             return rc;
3421         }
3422     }
3423 
3424     updatePostPreviewParameters();
3425     m_stateMachine.setPreviewCallbackNeeded(true);
3426 
3427     // if job id is non-zero, that means the postproc init job is already
3428     // pending or complete
3429     if (mInitPProcJob == 0) {
3430         mInitPProcJob = deferPPInit();
3431         if (mInitPProcJob == 0) {
3432             LOGE("Unable to initialize postprocessor, mCameraHandle = %p",
3433                      mCameraHandle);
3434             rc = -ENOMEM;
3435             m_perfLock.lock_rel();
3436             return rc;
3437         }
3438     }
3439     m_perfLock.lock_rel();
3440 
3441     if (rc == NO_ERROR) {
3442         // Set power Hint for preview
3443         m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, true);
3444     }
3445 
3446     LOGI("X rc = %d", rc);
3447     return rc;
3448 }
3449 
updatePostPreviewParameters()3450 int32_t QCamera2HardwareInterface::updatePostPreviewParameters() {
3451     // Enable OIS only in Camera mode and 4k2k camcoder mode
3452     int32_t rc = NO_ERROR;
3453     rc = mParameters.updateOisValue(1);
3454     return NO_ERROR;
3455 }
3456 
3457 /*===========================================================================
3458  * FUNCTION   : stopPreview
3459  *
3460  * DESCRIPTION: stop preview impl
3461  *
3462  * PARAMETERS : none
3463  *
3464  * RETURN     : int32_t type of status
3465  *              NO_ERROR  -- success
3466  *              none-zero failure code
3467  *==========================================================================*/
stopPreview()3468 int QCamera2HardwareInterface::stopPreview()
3469 {
3470     KPI_ATRACE_CALL();
3471     LOGI("E");
3472     mNumPreviewFaces = -1;
3473     mActiveAF = false;
3474 
3475     // Disable power Hint for preview
3476     m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, false);
3477 
3478     m_perfLock.lock_acq();
3479 
3480     // stop preview stream
3481     stopChannel(QCAMERA_CH_TYPE_CALLBACK);
3482     stopChannel(QCAMERA_CH_TYPE_ZSL);
3483     stopChannel(QCAMERA_CH_TYPE_PREVIEW);
3484     stopChannel(QCAMERA_CH_TYPE_RAW);
3485 
3486     m_cbNotifier.flushPreviewNotifications();
3487     //add for ts makeup
3488 #ifdef TARGET_TS_MAKEUP
3489     ts_makeup_finish();
3490 #endif
3491     // delete all channels from preparePreview
3492     unpreparePreview();
3493 
3494     m_perfLock.lock_rel();
3495 
3496     LOGI("X");
3497     return NO_ERROR;
3498 }
3499 
3500 /*===========================================================================
3501  * FUNCTION   : storeMetaDataInBuffers
3502  *
3503  * DESCRIPTION: enable store meta data in buffers for video frames impl
3504  *
3505  * PARAMETERS :
3506  *   @enable  : flag if need enable
3507  *
3508  * RETURN     : int32_t type of status
3509  *              NO_ERROR  -- success
3510  *              none-zero failure code
3511  *==========================================================================*/
storeMetaDataInBuffers(int enable)3512 int QCamera2HardwareInterface::storeMetaDataInBuffers(int enable)
3513 {
3514     mStoreMetaDataInFrame = enable;
3515     return NO_ERROR;
3516 }
3517 
3518 /*===========================================================================
3519  * FUNCTION   : preStartRecording
3520  *
3521  * DESCRIPTION: Prepare start recording impl
3522  *
3523  * PARAMETERS : none
3524  *
3525  * RETURN     : int32_t type of status
3526  *              NO_ERROR  -- success
3527  *              none-zero failure code
3528  *==========================================================================*/
preStartRecording()3529 int QCamera2HardwareInterface::preStartRecording()
3530 {
3531     int32_t rc = NO_ERROR;
3532     LOGH("E");
3533     if (mParameters.getRecordingHintValue() == false) {
3534 
3535         // Give HWI control to restart preview only in single camera mode.
3536         // In dual-cam mode, this control belongs to muxer.
3537         if (getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
3538             LOGH("start recording when hint is false, stop preview first");
3539             stopPreview();
3540 
3541             // Set recording hint to TRUE
3542             mParameters.updateRecordingHintValue(TRUE);
3543             rc = preparePreview();
3544             if (rc == NO_ERROR) {
3545                 rc = startPreview();
3546             }
3547         }
3548         else
3549         {
3550             // For dual cam mode, update the flag mPreviewRestartNeeded to true
3551             // Restart control will be handled by muxer.
3552             mPreviewRestartNeeded = true;
3553         }
3554     }
3555 
3556     LOGH("X rc = %d", rc);
3557     return rc;
3558 }
3559 
3560 /*===========================================================================
3561  * FUNCTION   : startRecording
3562  *
3563  * DESCRIPTION: start recording impl
3564  *
3565  * PARAMETERS : none
3566  *
3567  * RETURN     : int32_t type of status
3568  *              NO_ERROR  -- success
3569  *              none-zero failure code
3570  *==========================================================================*/
startRecording()3571 int QCamera2HardwareInterface::startRecording()
3572 {
3573     int32_t rc = NO_ERROR;
3574 
3575     LOGI("E");
3576     //link meta stream with video channel if low power mode.
3577     if (isLowPowerMode()) {
3578         // Find and try to link a metadata stream from preview channel
3579         QCameraChannel *pMetaChannel = NULL;
3580         QCameraStream *pMetaStream = NULL;
3581         QCameraChannel *pVideoChannel = m_channels[QCAMERA_CH_TYPE_VIDEO];
3582 
3583         if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
3584             pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
3585             uint32_t streamNum = pMetaChannel->getNumOfStreams();
3586             QCameraStream *pStream = NULL;
3587             for (uint32_t i = 0 ; i < streamNum ; i++ ) {
3588                 pStream = pMetaChannel->getStreamByIndex(i);
3589                 if ((NULL != pStream) &&
3590                         (CAM_STREAM_TYPE_METADATA == pStream->getMyType())) {
3591                     pMetaStream = pStream;
3592                     break;
3593                 }
3594             }
3595         }
3596 
3597         if ((NULL != pMetaChannel) && (NULL != pMetaStream)) {
3598             rc = pVideoChannel->linkStream(pMetaChannel, pMetaStream);
3599             if (NO_ERROR != rc) {
3600                 LOGW("Metadata stream link failed %d", rc);
3601             }
3602         }
3603     }
3604 
3605     if (rc == NO_ERROR) {
3606         rc = startChannel(QCAMERA_CH_TYPE_VIDEO);
3607     }
3608 
3609     if (mParameters.isTNRSnapshotEnabled() && !isLowPowerMode()) {
3610         QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
3611         if (!mParameters.is4k2kVideoResolution()) {
3612             // Find and try to link a metadata stream from preview channel
3613             QCameraChannel *pMetaChannel = NULL;
3614             QCameraStream *pMetaStream = NULL;
3615 
3616             if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
3617                 pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
3618                 uint32_t streamNum = pMetaChannel->getNumOfStreams();
3619                 QCameraStream *pStream = NULL;
3620                 for (uint32_t i = 0 ; i < streamNum ; i++ ) {
3621                     pStream = pMetaChannel->getStreamByIndex(i);
3622                     if ((NULL != pStream) &&
3623                             (CAM_STREAM_TYPE_METADATA ==
3624                             pStream->getMyType())) {
3625                         pMetaStream = pStream;
3626                         break;
3627                     }
3628                 }
3629             }
3630 
3631             if ((NULL != pMetaChannel) && (NULL != pMetaStream)) {
3632                 rc = pChannel->linkStream(pMetaChannel, pMetaStream);
3633                 if (NO_ERROR != rc) {
3634                     LOGW("Metadata stream link failed %d", rc);
3635                 }
3636             }
3637         }
3638         LOGH("START snapshot Channel for TNR processing");
3639         rc = pChannel->start();
3640     }
3641 
3642     if (rc == NO_ERROR) {
3643         // Set power Hint for video encoding
3644         m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, true);
3645     }
3646 
3647     LOGI("X rc = %d", rc);
3648     return rc;
3649 }
3650 
3651 /*===========================================================================
3652  * FUNCTION   : stopRecording
3653  *
3654  * DESCRIPTION: stop recording impl
3655  *
3656  * PARAMETERS : none
3657  *
3658  * RETURN     : int32_t type of status
3659  *              NO_ERROR  -- success
3660  *              none-zero failure code
3661  *==========================================================================*/
stopRecording()3662 int QCamera2HardwareInterface::stopRecording()
3663 {
3664     LOGI("E");
3665     // stop snapshot channel
3666     if (mParameters.isTNRSnapshotEnabled()) {
3667         LOGH("STOP snapshot Channel for TNR processing");
3668         stopChannel(QCAMERA_CH_TYPE_SNAPSHOT);
3669     }
3670     int rc = stopChannel(QCAMERA_CH_TYPE_VIDEO);
3671 
3672     // Disable power hint for video encoding
3673     m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, false);
3674 
3675     LOGI("X rc = %d", rc);
3676     return rc;
3677 }
3678 
3679 /*===========================================================================
3680  * FUNCTION   : releaseRecordingFrame
3681  *
3682  * DESCRIPTION: return video frame impl
3683  *
3684  * PARAMETERS :
3685  *   @opaque  : ptr to video frame to be returned
3686  *
3687  * RETURN     : int32_t type of status
3688  *              NO_ERROR  -- success
3689  *              none-zero failure code
3690  *==========================================================================*/
releaseRecordingFrame(const void * opaque)3691 int QCamera2HardwareInterface::releaseRecordingFrame(const void * opaque)
3692 {
3693     int32_t rc = UNKNOWN_ERROR;
3694     QCameraVideoChannel *pChannel =
3695         (QCameraVideoChannel *)m_channels[QCAMERA_CH_TYPE_VIDEO];
3696     LOGD("opaque data = %p",opaque);
3697     if(pChannel != NULL) {
3698         rc = pChannel->releaseFrame(opaque, mStoreMetaDataInFrame > 0);
3699     }
3700     return rc;
3701 }
3702 
3703 /*===========================================================================
3704  * FUNCTION   : autoFocus
3705  *
3706  * DESCRIPTION: start auto focus impl
3707  *
3708  * PARAMETERS : none
3709  *
3710  * RETURN     : int32_t type of status
3711  *              NO_ERROR  -- success
3712  *              none-zero failure code
3713  *==========================================================================*/
autoFocus()3714 int QCamera2HardwareInterface::autoFocus()
3715 {
3716     int rc = NO_ERROR;
3717     cam_focus_mode_type focusMode = mParameters.getFocusMode();
3718     LOGH("E");
3719 
3720     m_currentFocusState = CAM_AF_STATE_INACTIVE;
3721 
3722     switch (focusMode) {
3723     case CAM_FOCUS_MODE_AUTO:
3724     case CAM_FOCUS_MODE_MACRO:
3725     case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
3726     case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
3727         mActiveAF = true;
3728         LOGI("Send AUTO FOCUS event. focusMode=%d, m_currentFocusState=%d",
3729                 focusMode, m_currentFocusState);
3730         rc = mCameraHandle->ops->do_auto_focus(mCameraHandle->camera_handle);
3731         break;
3732     case CAM_FOCUS_MODE_INFINITY:
3733     case CAM_FOCUS_MODE_FIXED:
3734     case CAM_FOCUS_MODE_EDOF:
3735     default:
3736         LOGI("No ops in focusMode (%d)", focusMode);
3737         rc = sendEvtNotify(CAMERA_MSG_FOCUS, true, 0);
3738         break;
3739     }
3740 
3741     if (NO_ERROR != rc) {
3742         mActiveAF = false;
3743     }
3744     LOGH("X rc = %d", rc);
3745     return rc;
3746 }
3747 
3748 /*===========================================================================
3749  * FUNCTION   : cancelAutoFocus
3750  *
3751  * DESCRIPTION: cancel auto focus impl
3752  *
3753  * PARAMETERS : none
3754  *
3755  * RETURN     : int32_t type of status
3756  *              NO_ERROR  -- success
3757  *              none-zero failure code
3758  *==========================================================================*/
cancelAutoFocus()3759 int QCamera2HardwareInterface::cancelAutoFocus()
3760 {
3761     int rc = NO_ERROR;
3762     cam_focus_mode_type focusMode = mParameters.getFocusMode();
3763 
3764     switch (focusMode) {
3765     case CAM_FOCUS_MODE_AUTO:
3766     case CAM_FOCUS_MODE_MACRO:
3767     case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
3768     case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
3769         mActiveAF = false;
3770         rc = mCameraHandle->ops->cancel_auto_focus(mCameraHandle->camera_handle);
3771         break;
3772     case CAM_FOCUS_MODE_INFINITY:
3773     case CAM_FOCUS_MODE_FIXED:
3774     case CAM_FOCUS_MODE_EDOF:
3775     default:
3776         LOGD("No ops in focusMode (%d)", focusMode);
3777         break;
3778     }
3779     return rc;
3780 }
3781 
3782 /*===========================================================================
3783  * FUNCTION   : processUFDumps
3784  *
3785  * DESCRIPTION: process UF jpeg dumps for refocus support
3786  *
3787  * PARAMETERS :
3788  *   @evt     : payload of jpeg event, including information about jpeg encoding
3789  *              status, jpeg size and so on.
3790  *
3791  * RETURN     : int32_t type of status
3792  *              NO_ERROR  -- success
3793  *              none-zero failure code
3794  *
3795  * NOTE       : none
3796  *==========================================================================*/
processUFDumps(qcamera_jpeg_evt_payload_t * evt)3797 bool QCamera2HardwareInterface::processUFDumps(qcamera_jpeg_evt_payload_t *evt)
3798 {
3799    bool ret = true;
3800    if (mParameters.isUbiRefocus()) {
3801        int index = (int)getOutputImageCount();
3802        bool allFocusImage = (index == ((int)mParameters.getRefocusOutputCount() - 1));
3803        char name[FILENAME_MAX];
3804 
3805        camera_memory_t *jpeg_mem = NULL;
3806        omx_jpeg_ouput_buf_t *jpeg_out = NULL;
3807        size_t dataLen;
3808        uint8_t *dataPtr;
3809        if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
3810            LOGE("Init PProc Deferred work failed");
3811            return false;
3812        }
3813        if (!m_postprocessor.getJpegMemOpt()) {
3814            dataLen = evt->out_data.buf_filled_len;
3815            dataPtr = evt->out_data.buf_vaddr;
3816        } else {
3817            jpeg_out  = (omx_jpeg_ouput_buf_t*) evt->out_data.buf_vaddr;
3818            if (!jpeg_out) {
3819               LOGE("Null pointer detected");
3820               return false;
3821            }
3822            jpeg_mem = (camera_memory_t *)jpeg_out->mem_hdl;
3823            if (!jpeg_mem) {
3824               LOGE("Null pointer detected");
3825               return false;
3826            }
3827            dataPtr = (uint8_t *)jpeg_mem->data;
3828            dataLen = jpeg_mem->size;
3829        }
3830 
3831        if (allFocusImage)  {
3832            snprintf(name, sizeof(name), "AllFocusImage");
3833            index = -1;
3834        } else {
3835            snprintf(name, sizeof(name), "%d", 0);
3836        }
3837        CAM_DUMP_TO_FILE(QCAMERA_DUMP_FRM_LOCATION"ubifocus", name, index, "jpg",
3838            dataPtr, dataLen);
3839        LOGD("Dump the image %d %d allFocusImage %d",
3840            getOutputImageCount(), index, allFocusImage);
3841        setOutputImageCount(getOutputImageCount() + 1);
3842        if (!allFocusImage) {
3843            ret = false;
3844        }
3845    }
3846    return ret;
3847 }
3848 
3849 /*===========================================================================
3850  * FUNCTION   : unconfigureAdvancedCapture
3851  *
3852  * DESCRIPTION: unconfigure Advanced Capture.
3853  *
3854  * PARAMETERS : none
3855  *
3856  * RETURN     : int32_t type of status
3857  *              NO_ERROR  -- success
3858  *              none-zero failure code
3859  *==========================================================================*/
unconfigureAdvancedCapture()3860 int32_t QCamera2HardwareInterface::unconfigureAdvancedCapture()
3861 {
3862     int32_t rc = NO_ERROR;
3863 
3864     if (mAdvancedCaptureConfigured) {
3865 
3866         mAdvancedCaptureConfigured = false;
3867 
3868         if(mIs3ALocked) {
3869             mParameters.set3ALock(false);
3870             mIs3ALocked = false;
3871         }
3872         if (mParameters.isHDREnabled() || mParameters.isAEBracketEnabled()) {
3873             rc = mParameters.setToneMapMode(true, true);
3874             if (rc != NO_ERROR) {
3875                 LOGW("Failed to enable tone map during HDR/AEBracketing");
3876             }
3877             mHDRBracketingEnabled = false;
3878             rc = mParameters.stopAEBracket();
3879         } else if ((mParameters.isChromaFlashEnabled())
3880                 || (mFlashNeeded && !mLongshotEnabled)
3881                 || (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF)
3882                 || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
3883             rc = mParameters.resetFrameCapture(TRUE);
3884         } else if (mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
3885             rc = configureAFBracketing(false);
3886         } else if (mParameters.isOptiZoomEnabled()) {
3887             rc = mParameters.setAndCommitZoom(mZoomLevel);
3888             setDisplaySkip(FALSE, CAMERA_MAX_PARAM_APPLY_DELAY);
3889         } else if (mParameters.isStillMoreEnabled()) {
3890             cam_still_more_t stillmore_config = mParameters.getStillMoreSettings();
3891             stillmore_config.burst_count = 0;
3892             mParameters.setStillMoreSettings(stillmore_config);
3893 
3894             /* If SeeMore is running, it will handle re-enabling tone map */
3895             if (!mParameters.isSeeMoreEnabled() && !mParameters.isLTMForSeeMoreEnabled()) {
3896                 rc = mParameters.setToneMapMode(true, true);
3897                 if (rc != NO_ERROR) {
3898                     LOGW("Failed to enable tone map during StillMore");
3899                 }
3900             }
3901 
3902             /* Re-enable Tintless */
3903             mParameters.setTintless(true);
3904         } else {
3905             LOGW("No Advanced Capture feature enabled!!");
3906             rc = BAD_VALUE;
3907         }
3908     }
3909 
3910     return rc;
3911 }
3912 
3913 /*===========================================================================
3914  * FUNCTION   : configureAdvancedCapture
3915  *
3916  * DESCRIPTION: configure Advanced Capture.
3917  *
3918  * PARAMETERS : none
3919  *
3920  * RETURN     : int32_t type of status
3921  *              NO_ERROR  -- success
3922  *              none-zero failure code
3923  *==========================================================================*/
configureAdvancedCapture()3924 int32_t QCamera2HardwareInterface::configureAdvancedCapture()
3925 {
3926     LOGH("E");
3927     int32_t rc = NO_ERROR;
3928 
3929     rc = mParameters.checkFeatureConcurrency();
3930     if (rc != NO_ERROR) {
3931         LOGE("Cannot support Advanced capture modes");
3932         return rc;
3933     }
3934 
3935     setOutputImageCount(0);
3936     mInputCount = 0;
3937     mAdvancedCaptureConfigured = true;
3938     /* Display should be disabled for advanced modes */
3939     bool bSkipDisplay = true;
3940 
3941     if (getRelatedCamSyncInfo()->mode == CAM_MODE_SECONDARY) {
3942         // no Advance capture settings for Aux camera
3943         LOGH("X Secondary Camera, no need to process!! ");
3944         return rc;
3945     }
3946 
3947     /* Do not stop display if in stillmore livesnapshot */
3948     if (mParameters.isStillMoreEnabled() &&
3949             mParameters.isSeeMoreEnabled()) {
3950         bSkipDisplay = false;
3951     }
3952     if (mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
3953         rc = configureAFBracketing();
3954     } else if (mParameters.isOptiZoomEnabled()) {
3955         rc = configureOptiZoom();
3956     } else if(mParameters.isHDREnabled()) {
3957         rc = configureHDRBracketing();
3958         if (mHDRBracketingEnabled) {
3959             rc = mParameters.setToneMapMode(false, true);
3960             if (rc != NO_ERROR) {
3961                 LOGW("Failed to disable tone map during HDR");
3962             }
3963         }
3964     } else if (mParameters.isAEBracketEnabled()) {
3965         rc = mParameters.setToneMapMode(false, true);
3966         if (rc != NO_ERROR) {
3967             LOGW("Failed to disable tone map during AEBracketing");
3968         }
3969         rc = configureAEBracketing();
3970     } else if (mParameters.isStillMoreEnabled()) {
3971         rc = configureStillMore();
3972     } else if ((mParameters.isChromaFlashEnabled())
3973             || (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF)
3974             || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
3975         rc = mParameters.configFrameCapture(TRUE);
3976     } else if (mFlashNeeded && !mLongshotEnabled) {
3977         rc = mParameters.configFrameCapture(TRUE);
3978         bSkipDisplay = false;
3979     } else {
3980         LOGH("Advanced Capture feature not enabled!! ");
3981         mAdvancedCaptureConfigured = false;
3982         bSkipDisplay = false;
3983     }
3984 
3985     LOGH("Stop preview temporarily for advanced captures");
3986     setDisplaySkip(bSkipDisplay);
3987 
3988     LOGH("X rc = %d", rc);
3989     return rc;
3990 }
3991 
3992 /*===========================================================================
3993  * FUNCTION   : configureAFBracketing
3994  *
3995  * DESCRIPTION: configure AF Bracketing.
3996  *
3997  * PARAMETERS : none
3998  *
3999  * RETURN     : int32_t type of status
4000  *              NO_ERROR  -- success
4001  *              none-zero failure code
4002  *==========================================================================*/
configureAFBracketing(bool enable)4003 int32_t QCamera2HardwareInterface::configureAFBracketing(bool enable)
4004 {
4005     LOGH("E");
4006     int32_t rc = NO_ERROR;
4007     cam_af_bracketing_t *af_bracketing_need;
4008 
4009     if (mParameters.isUbiRefocus()) {
4010         af_bracketing_need =
4011                 &gCamCapability[mCameraId]->refocus_af_bracketing_need;
4012     } else {
4013         af_bracketing_need =
4014                 &gCamCapability[mCameraId]->ubifocus_af_bracketing_need;
4015     }
4016 
4017     //Enable AF Bracketing.
4018     cam_af_bracketing_t afBracket;
4019     memset(&afBracket, 0, sizeof(cam_af_bracketing_t));
4020     afBracket.enable = enable;
4021     afBracket.burst_count = af_bracketing_need->burst_count;
4022 
4023     for(int8_t i = 0; i < MAX_AF_BRACKETING_VALUES; i++) {
4024         afBracket.focus_steps[i] = af_bracketing_need->focus_steps[i];
4025         LOGH("focus_step[%d] = %d", i, afBracket.focus_steps[i]);
4026     }
4027     //Send cmd to backend to set AF Bracketing for Ubi Focus.
4028     rc = mParameters.commitAFBracket(afBracket);
4029     if ( NO_ERROR != rc ) {
4030         LOGE("cannot configure AF bracketing");
4031         return rc;
4032     }
4033     if (enable) {
4034         mParameters.set3ALock(true);
4035         mIs3ALocked = true;
4036     }
4037     LOGH("X rc = %d", rc);
4038     return rc;
4039 }
4040 
4041 /*===========================================================================
4042  * FUNCTION   : configureHDRBracketing
4043  *
4044  * DESCRIPTION: configure HDR Bracketing.
4045  *
4046  * PARAMETERS : none
4047  *
4048  * RETURN     : int32_t type of status
4049  *              NO_ERROR  -- success
4050  *              none-zero failure code
4051  *==========================================================================*/
configureHDRBracketing()4052 int32_t QCamera2HardwareInterface::configureHDRBracketing()
4053 {
4054     LOGH("E");
4055     int32_t rc = NO_ERROR;
4056 
4057     cam_hdr_bracketing_info_t& hdrBracketingSetting =
4058             gCamCapability[mCameraId]->hdr_bracketing_setting;
4059 
4060     // 'values' should be in "idx1,idx2,idx3,..." format
4061     uint32_t hdrFrameCount =
4062             hdrBracketingSetting.num_frames;
4063     LOGH("HDR values %d, %d frame count: %u",
4064           (int8_t) hdrBracketingSetting.exp_val.values[0],
4065           (int8_t) hdrBracketingSetting.exp_val.values[1],
4066           hdrFrameCount);
4067 
4068     // Enable AE Bracketing for HDR
4069     cam_exp_bracketing_t aeBracket;
4070     memset(&aeBracket, 0, sizeof(cam_exp_bracketing_t));
4071     aeBracket.mode =
4072         hdrBracketingSetting.exp_val.mode;
4073 
4074     if (aeBracket.mode == CAM_EXP_BRACKETING_ON) {
4075         mHDRBracketingEnabled = true;
4076     }
4077 
4078     String8 tmp;
4079     for (uint32_t i = 0; i < hdrFrameCount; i++) {
4080         tmp.appendFormat("%d",
4081             (int8_t) hdrBracketingSetting.exp_val.values[i]);
4082         tmp.append(",");
4083     }
4084     if (mParameters.isHDR1xFrameEnabled()
4085         && mParameters.isHDR1xExtraBufferNeeded()) {
4086             tmp.appendFormat("%d", 0);
4087             tmp.append(",");
4088     }
4089 
4090     if( !tmp.isEmpty() &&
4091         ( MAX_EXP_BRACKETING_LENGTH > tmp.length() ) ) {
4092         //Trim last comma
4093         memset(aeBracket.values, '\0', MAX_EXP_BRACKETING_LENGTH);
4094         memcpy(aeBracket.values, tmp.string(), tmp.length() - 1);
4095     }
4096 
4097     LOGH("HDR config values %s",
4098           aeBracket.values);
4099     rc = mParameters.setHDRAEBracket(aeBracket);
4100     if ( NO_ERROR != rc ) {
4101         LOGE("cannot configure HDR bracketing");
4102         return rc;
4103     }
4104     LOGH("X rc = %d", rc);
4105     return rc;
4106 }
4107 
4108 /*===========================================================================
4109  * FUNCTION   : configureAEBracketing
4110  *
4111  * DESCRIPTION: configure AE Bracketing.
4112  *
4113  * PARAMETERS : none
4114  *
4115  * RETURN     : int32_t type of status
4116  *              NO_ERROR  -- success
4117  *              none-zero failure code
4118  *==========================================================================*/
configureAEBracketing()4119 int32_t QCamera2HardwareInterface::configureAEBracketing()
4120 {
4121     LOGH("E");
4122     int32_t rc = NO_ERROR;
4123 
4124     rc = mParameters.setAEBracketing();
4125     if ( NO_ERROR != rc ) {
4126         LOGE("cannot configure AE bracketing");
4127         return rc;
4128     }
4129     LOGH("X rc = %d", rc);
4130     return rc;
4131 }
4132 
4133 /*===========================================================================
4134  * FUNCTION   : configureOptiZoom
4135  *
4136  * DESCRIPTION: configure Opti Zoom.
4137  *
4138  * PARAMETERS : none
4139  *
4140  * RETURN     : int32_t type of status
4141  *              NO_ERROR  -- success
4142  *              none-zero failure code
4143  *==========================================================================*/
configureOptiZoom()4144 int32_t QCamera2HardwareInterface::configureOptiZoom()
4145 {
4146     int32_t rc = NO_ERROR;
4147 
4148     //store current zoom level.
4149     mZoomLevel = mParameters.getParmZoomLevel();
4150 
4151     //set zoom level to 1x;
4152     mParameters.setAndCommitZoom(0);
4153 
4154     mParameters.set3ALock(true);
4155     mIs3ALocked = true;
4156 
4157     return rc;
4158 }
4159 
4160 /*===========================================================================
4161  * FUNCTION   : configureStillMore
4162  *
4163  * DESCRIPTION: configure StillMore.
4164  *
4165  * PARAMETERS : none
4166  *
4167  * RETURN     : int32_t type of status
4168  *              NO_ERROR  -- success
4169  *              none-zero failure code
4170  *==========================================================================*/
configureStillMore()4171 int32_t QCamera2HardwareInterface::configureStillMore()
4172 {
4173     int32_t rc = NO_ERROR;
4174     uint8_t burst_cnt = 0;
4175     cam_still_more_t stillmore_config;
4176     cam_still_more_t stillmore_cap;
4177 
4178     /* Disable Tone Map. If seemore is enabled, it will handle disabling it. */
4179     if (!mParameters.isSeeMoreEnabled() && !mParameters.isLTMForSeeMoreEnabled()) {
4180         rc = mParameters.setToneMapMode(false, true);
4181         if (rc != NO_ERROR) {
4182             LOGW("Failed to disable tone map during StillMore");
4183         }
4184     }
4185 
4186     /* Lock 3A */
4187     mParameters.set3ALock(true);
4188     mIs3ALocked = true;
4189 
4190     /* Disable Tintless */
4191     mParameters.setTintless(false);
4192 
4193     /* Initialize burst count from capability */
4194     stillmore_cap = mParameters.getStillMoreCapability();
4195     burst_cnt = stillmore_cap.max_burst_count;
4196 
4197     /* Reconfigure burst count from dynamic scene data */
4198     cam_dyn_img_data_t dynamic_img_data = mParameters.getDynamicImgData();
4199     if (dynamic_img_data.input_count >= stillmore_cap.min_burst_count &&
4200             dynamic_img_data.input_count <= stillmore_cap.max_burst_count) {
4201         burst_cnt = dynamic_img_data.input_count;
4202     }
4203 
4204     /* Reconfigure burst count in the case of liveshot */
4205     if (mParameters.isSeeMoreEnabled()) {
4206         burst_cnt = 1;
4207     }
4208 
4209     /* Reconfigure burst count from user input */
4210     char prop[PROPERTY_VALUE_MAX];
4211     property_get("persist.camera.imglib.stillmore", prop, "0");
4212     uint8_t burst_setprop = (uint32_t)atoi(prop);
4213     if (burst_setprop != 0)  {
4214        if ((burst_setprop < stillmore_cap.min_burst_count) ||
4215                (burst_setprop > stillmore_cap.max_burst_count)) {
4216            burst_cnt = stillmore_cap.max_burst_count;
4217        } else {
4218            burst_cnt = burst_setprop;
4219        }
4220     }
4221 
4222     memset(&stillmore_config, 0, sizeof(cam_still_more_t));
4223     stillmore_config.burst_count = burst_cnt;
4224     mParameters.setStillMoreSettings(stillmore_config);
4225 
4226     LOGH("Stillmore burst %d", burst_cnt);
4227 
4228     return rc;
4229 }
4230 
4231 /*===========================================================================
4232  * FUNCTION   : stopAdvancedCapture
4233  *
4234  * DESCRIPTION: stops advanced capture based on capture type
4235  *
4236  * PARAMETERS :
4237  *   @pChannel : channel.
4238  *
4239  * RETURN     : int32_t type of status
4240  *              NO_ERROR  -- success
4241  *              none-zero failure code
4242  *==========================================================================*/
stopAdvancedCapture(QCameraPicChannel * pChannel)4243 int32_t QCamera2HardwareInterface::stopAdvancedCapture(
4244         QCameraPicChannel *pChannel)
4245 {
4246     LOGH("stop bracketig");
4247     int32_t rc = NO_ERROR;
4248 
4249     if(mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
4250         rc = pChannel->stopAdvancedCapture(MM_CAMERA_AF_BRACKETING);
4251     } else if (mParameters.isChromaFlashEnabled()
4252             || (mFlashNeeded && !mLongshotEnabled)
4253             || (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF)
4254             || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
4255         rc = pChannel->stopAdvancedCapture(MM_CAMERA_FRAME_CAPTURE);
4256     } else if(mParameters.isHDREnabled()
4257             || mParameters.isAEBracketEnabled()) {
4258         rc = pChannel->stopAdvancedCapture(MM_CAMERA_AE_BRACKETING);
4259     } else if (mParameters.isOptiZoomEnabled()) {
4260         rc = pChannel->stopAdvancedCapture(MM_CAMERA_ZOOM_1X);
4261     } else if (mParameters.isStillMoreEnabled()) {
4262         LOGH("stopAdvancedCapture not needed for StillMore");
4263     } else {
4264         LOGH("No Advanced Capture feature enabled!");
4265         rc = BAD_VALUE;
4266     }
4267     return rc;
4268 }
4269 
4270 /*===========================================================================
4271  * FUNCTION   : startAdvancedCapture
4272  *
4273  * DESCRIPTION: starts advanced capture based on capture type
4274  *
4275  * PARAMETERS :
4276  *   @pChannel : channel.
4277  *
4278  * RETURN     : int32_t type of status
4279  *              NO_ERROR  -- success
4280  *              none-zero failure code
4281  *==========================================================================*/
startAdvancedCapture(QCameraPicChannel * pChannel)4282 int32_t QCamera2HardwareInterface::startAdvancedCapture(
4283         QCameraPicChannel *pChannel)
4284 {
4285     LOGH("Start bracketing");
4286     int32_t rc = NO_ERROR;
4287 
4288     if(mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
4289         rc = pChannel->startAdvancedCapture(MM_CAMERA_AF_BRACKETING);
4290     } else if (mParameters.isOptiZoomEnabled()) {
4291         rc = pChannel->startAdvancedCapture(MM_CAMERA_ZOOM_1X);
4292     } else if (mParameters.isStillMoreEnabled()) {
4293         LOGH("startAdvancedCapture not needed for StillMore");
4294     } else if (mParameters.isHDREnabled()
4295             || mParameters.isAEBracketEnabled()) {
4296         rc = pChannel->startAdvancedCapture(MM_CAMERA_AE_BRACKETING);
4297     } else if (mParameters.isChromaFlashEnabled()
4298             || (mFlashNeeded && !mLongshotEnabled)
4299             || (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF)
4300             || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
4301         cam_capture_frame_config_t config = mParameters.getCaptureFrameConfig();
4302         rc = pChannel->startAdvancedCapture(MM_CAMERA_FRAME_CAPTURE, &config);
4303     } else {
4304         LOGE("No Advanced Capture feature enabled!");
4305         rc = BAD_VALUE;
4306     }
4307     return rc;
4308 }
4309 
4310 /*===========================================================================
4311  * FUNCTION   : preTakePicture
4312  *
4313  * DESCRIPTION: Prepare take picture impl, Restarts preview if necessary
4314  *
4315  * PARAMETERS : none
4316  *
4317  * RETURN     : int32_t type of status
4318  *              NO_ERROR  -- success
4319  *              none-zero failure code
4320  *==========================================================================*/
preTakePicture()4321 int QCamera2HardwareInterface::preTakePicture()
4322 {
4323     int32_t rc = NO_ERROR;
4324     LOGH("E");
4325     if (mParameters.getRecordingHintValue() == true) {
4326 
4327         // Give HWI control to restart preview only in single camera mode.
4328         // In dual-cam mode, this control belongs to muxer.
4329         if (getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
4330             LOGH("restart preview if rec hint is true and preview is running");
4331             stopPreview();
4332             mParameters.updateRecordingHintValue(FALSE);
4333             // start preview again
4334             rc = preparePreview();
4335             if (rc == NO_ERROR) {
4336                 rc = startPreview();
4337                 if (rc != NO_ERROR) {
4338                     unpreparePreview();
4339                 }
4340             }
4341         }
4342         else
4343         {
4344             // For dual cam mode, update the flag mPreviewRestartNeeded to true
4345             // Restart control will be handled by muxer.
4346             mPreviewRestartNeeded = true;
4347         }
4348     }
4349 
4350     LOGH("X rc = %d", rc);
4351     return rc;
4352 }
4353 
4354 /*===========================================================================
4355  * FUNCTION   : takePicture
4356  *
4357  * DESCRIPTION: take picture impl
4358  *
4359  * PARAMETERS : none
4360  *
4361  * RETURN     : int32_t type of status
4362  *              NO_ERROR  -- success
4363  *              none-zero failure code
4364  *==========================================================================*/
takePicture()4365 int QCamera2HardwareInterface::takePicture()
4366 {
4367     int rc = NO_ERROR;
4368 
4369     // Get total number for snapshots (retro + regular)
4370     uint8_t numSnapshots = mParameters.getNumOfSnapshots();
4371     // Get number of retro-active snapshots
4372     uint8_t numRetroSnapshots = mParameters.getNumOfRetroSnapshots();
4373     LOGH("E");
4374 
4375     //Set rotation value from user settings as Jpeg rotation
4376     //to configure back-end modules.
4377     mParameters.setJpegRotation(mParameters.getRotation());
4378 
4379     // Check if retro-active snapshots are not enabled
4380     if (!isRetroPicture() || !mParameters.isZSLMode()) {
4381       numRetroSnapshots = 0;
4382       LOGH("Reset retro snaphot count to zero");
4383     }
4384 
4385     //Do special configure for advanced capture modes.
4386     rc = configureAdvancedCapture();
4387     if (rc != NO_ERROR) {
4388         LOGE("Unsupported capture call");
4389         return rc;
4390     }
4391 
4392     if (mAdvancedCaptureConfigured) {
4393         numSnapshots = mParameters.getBurstCountForAdvancedCapture();
4394     }
4395     LOGI("snap count = %d zsl = %d advanced = %d",
4396             numSnapshots, mParameters.isZSLMode(), mAdvancedCaptureConfigured);
4397 
4398     if (mParameters.isZSLMode()) {
4399         QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
4400         QCameraPicChannel *pPicChannel = (QCameraPicChannel *)pChannel;
4401         if (NULL != pPicChannel) {
4402 
4403             if (mParameters.getofflineRAW()) {
4404                 startRAWChannel(pPicChannel);
4405                 pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_RAW];
4406                 if (pPicChannel == NULL) {
4407                     LOGE("RAW Channel is NULL in Manual capture mode");
4408                     stopRAWChannel();
4409                     return UNKNOWN_ERROR;
4410                 }
4411             }
4412 
4413             rc = configureOnlineRotation(*pPicChannel);
4414             if (rc != NO_ERROR) {
4415                 LOGE("online rotation failed");
4416                 return rc;
4417             }
4418 
4419             // start postprocessor
4420             DeferWorkArgs args;
4421             memset(&args, 0, sizeof(DeferWorkArgs));
4422 
4423             args.pprocArgs = pPicChannel;
4424 
4425             // No need to wait for mInitPProcJob here, because it was
4426             // queued in startPreview, and will definitely be processed before
4427             // mReprocJob can begin.
4428             mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START,
4429                     args);
4430             if (mReprocJob == 0) {
4431                 LOGE("Failure: Unable to start pproc");
4432                 return -ENOMEM;
4433             }
4434 
4435             // Check if all preview buffers are mapped before creating
4436             // a jpeg session as preview stream buffers are queried during the same
4437             uint8_t numStreams = pChannel->getNumOfStreams();
4438             QCameraStream *pStream = NULL;
4439             QCameraStream *pPreviewStream = NULL;
4440             for (uint8_t i = 0 ; i < numStreams ; i++ ) {
4441                 pStream = pChannel->getStreamByIndex(i);
4442                 if (!pStream)
4443                     continue;
4444                 if (CAM_STREAM_TYPE_PREVIEW == pStream->getMyType()) {
4445                     pPreviewStream = pStream;
4446                     break;
4447                 }
4448             }
4449             if (pPreviewStream != NULL) {
4450                 Mutex::Autolock l(mMapLock);
4451                 QCameraMemory *pMemory = pStream->getStreamBufs();
4452                 if (!pMemory) {
4453                     LOGE("Error!! pMemory is NULL");
4454                     return -ENOMEM;
4455                 }
4456 
4457                 uint8_t waitCnt = 2;
4458                 while (!pMemory->checkIfAllBuffersMapped() && (waitCnt > 0)) {
4459                     LOGL(" Waiting for preview buffers to be mapped");
4460                     mMapCond.waitRelative(
4461                             mMapLock, CAMERA_DEFERRED_MAP_BUF_TIMEOUT);
4462                     LOGL("Wait completed!!");
4463                     waitCnt--;
4464                 }
4465                 // If all buffers are not mapped after retries, assert
4466                 assert(pMemory->checkIfAllBuffersMapped());
4467             } else {
4468                 assert(pPreviewStream);
4469             }
4470 
4471             // Create JPEG session
4472             mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION,
4473                     args);
4474             if (mJpegJob == 0) {
4475                 LOGE("Failed to queue CREATE_JPEG_SESSION");
4476                 if (NO_ERROR != waitDeferredWork(mReprocJob)) {
4477                         LOGE("Reprocess Deferred work was failed");
4478                 }
4479                 m_postprocessor.stop();
4480                 return -ENOMEM;
4481             }
4482 
4483             if (mAdvancedCaptureConfigured) {
4484                 rc = startAdvancedCapture(pPicChannel);
4485                 if (rc != NO_ERROR) {
4486                     LOGE("cannot start zsl advanced capture");
4487                     return rc;
4488                 }
4489             }
4490             if (mLongshotEnabled && mPrepSnapRun) {
4491                 mCameraHandle->ops->start_zsl_snapshot(
4492                         mCameraHandle->camera_handle,
4493                         pPicChannel->getMyHandle());
4494             }
4495             // If frame sync is ON and it is a SECONDARY camera,
4496             // we do not need to send the take picture command to interface
4497             // It will be handled along with PRIMARY camera takePicture request
4498             mm_camera_req_buf_t buf;
4499             memset(&buf, 0x0, sizeof(buf));
4500             if ((!mParameters.isAdvCamFeaturesEnabled() &&
4501                     !mFlashNeeded &&
4502                     !isLongshotEnabled() &&
4503                     getRelatedCamSyncInfo()->is_frame_sync_enabled) &&
4504                     (getRelatedCamSyncInfo()->sync_control ==
4505                     CAM_SYNC_RELATED_SENSORS_ON)) {
4506                 if (getRelatedCamSyncInfo()->mode == CAM_MODE_PRIMARY) {
4507                     buf.type = MM_CAMERA_REQ_FRAME_SYNC_BUF;
4508                     buf.num_buf_requested = numSnapshots;
4509                     rc = pPicChannel->takePicture(&buf);
4510                     if (rc != NO_ERROR) {
4511                         LOGE("FS_DBG cannot take ZSL picture, stop pproc");
4512                         if (NO_ERROR != waitDeferredWork(mReprocJob)) {
4513                             LOGE("Reprocess Deferred work failed");
4514                             return UNKNOWN_ERROR;
4515                         }
4516                         if (NO_ERROR != waitDeferredWork(mJpegJob)) {
4517                             LOGE("Jpeg Deferred work failed");
4518                             return UNKNOWN_ERROR;
4519                         }
4520                         m_postprocessor.stop();
4521                         return rc;
4522                     }
4523                     LOGI("PRIMARY camera: send frame sync takePicture!!");
4524                 }
4525             } else {
4526                 buf.type = MM_CAMERA_REQ_SUPER_BUF;
4527                 buf.num_buf_requested = numSnapshots;
4528                 buf.num_retro_buf_requested = numRetroSnapshots;
4529                 rc = pPicChannel->takePicture(&buf);
4530                 if (rc != NO_ERROR) {
4531                     LOGE("cannot take ZSL picture, stop pproc");
4532                         if (NO_ERROR != waitDeferredWork(mReprocJob)) {
4533                             LOGE("Reprocess Deferred work failed");
4534                             return UNKNOWN_ERROR;
4535                         }
4536                         if (NO_ERROR != waitDeferredWork(mJpegJob)) {
4537                             LOGE("Jpeg Deferred work failed");
4538                             return UNKNOWN_ERROR;
4539                         }
4540                     m_postprocessor.stop();
4541                     return rc;
4542                 }
4543             }
4544         } else {
4545             LOGE("ZSL channel is NULL");
4546             return UNKNOWN_ERROR;
4547         }
4548     } else {
4549 
4550         // start snapshot
4551         if (mParameters.isJpegPictureFormat() ||
4552                 mParameters.isNV16PictureFormat() ||
4553                 mParameters.isNV21PictureFormat()) {
4554 
4555             //STOP Preview for Non ZSL use case
4556             stopPreview();
4557 
4558             //Config CAPTURE channels
4559             rc = declareSnapshotStreams();
4560             if (NO_ERROR != rc) {
4561                 return rc;
4562             }
4563 
4564             rc = addCaptureChannel();
4565             if ((rc == NO_ERROR) &&
4566                     (NULL != m_channels[QCAMERA_CH_TYPE_CAPTURE])) {
4567 
4568                 if (!mParameters.getofflineRAW()) {
4569                     rc = configureOnlineRotation(
4570                         *m_channels[QCAMERA_CH_TYPE_CAPTURE]);
4571                     if (rc != NO_ERROR) {
4572                         LOGE("online rotation failed");
4573                         delChannel(QCAMERA_CH_TYPE_CAPTURE);
4574                         return rc;
4575                     }
4576                 }
4577 
4578                 DeferWorkArgs args;
4579                 memset(&args, 0, sizeof(DeferWorkArgs));
4580 
4581                 args.pprocArgs = m_channels[QCAMERA_CH_TYPE_CAPTURE];
4582 
4583                 // No need to wait for mInitPProcJob here, because it was
4584                 // queued in startPreview, and will definitely be processed before
4585                 // mReprocJob can begin.
4586                 mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START,
4587                         args);
4588                 if (mReprocJob == 0) {
4589                     LOGE("Failure: Unable to start pproc");
4590                     return -ENOMEM;
4591                 }
4592 
4593                 // Create JPEG session
4594                 mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION,
4595                         args);
4596                 if (mJpegJob == 0) {
4597                     LOGE("Failed to queue CREATE_JPEG_SESSION");
4598                     if (NO_ERROR != waitDeferredWork(mReprocJob)) {
4599                         LOGE("Reprocess Deferred work was failed");
4600                     }
4601                     m_postprocessor.stop();
4602                     return -ENOMEM;
4603                 }
4604 
4605                 // start catpure channel
4606                 rc =  m_channels[QCAMERA_CH_TYPE_CAPTURE]->start();
4607                 if (rc != NO_ERROR) {
4608                     LOGE("cannot start capture channel");
4609                     if (NO_ERROR != waitDeferredWork(mReprocJob)) {
4610                         LOGE("Reprocess Deferred work failed");
4611                         return UNKNOWN_ERROR;
4612                     }
4613                     if (NO_ERROR != waitDeferredWork(mJpegJob)) {
4614                         LOGE("Jpeg Deferred work failed");
4615                         return UNKNOWN_ERROR;
4616                     }
4617                     delChannel(QCAMERA_CH_TYPE_CAPTURE);
4618                     return rc;
4619                 }
4620 
4621                 QCameraPicChannel *pCapChannel =
4622                     (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_CAPTURE];
4623                 if (NULL != pCapChannel) {
4624                     if (mParameters.isUbiFocusEnabled() ||
4625                             mParameters.isUbiRefocus() ||
4626                             mParameters.isChromaFlashEnabled()) {
4627                         rc = startAdvancedCapture(pCapChannel);
4628                         if (rc != NO_ERROR) {
4629                             LOGE("cannot start advanced capture");
4630                             return rc;
4631                         }
4632                     }
4633                 }
4634                 if ( mLongshotEnabled ) {
4635                     rc = longShot();
4636                     if (NO_ERROR != rc) {
4637                         if (NO_ERROR != waitDeferredWork(mReprocJob)) {
4638                             LOGE("Reprocess Deferred work failed");
4639                             return UNKNOWN_ERROR;
4640                         }
4641                         if (NO_ERROR != waitDeferredWork(mJpegJob)) {
4642                             LOGE("Jpeg Deferred work failed");
4643                             return UNKNOWN_ERROR;
4644                         }
4645                         delChannel(QCAMERA_CH_TYPE_CAPTURE);
4646                         return rc;
4647                     }
4648                 }
4649             } else {
4650                 LOGE("cannot add capture channel");
4651                 delChannel(QCAMERA_CH_TYPE_CAPTURE);
4652                 return rc;
4653             }
4654         } else {
4655             // Stop Preview before taking NZSL snapshot
4656             stopPreview();
4657 
4658             rc = mParameters.updateRAW(gCamCapability[mCameraId]->raw_dim[0]);
4659             if (NO_ERROR != rc) {
4660                 LOGE("Raw dimension update failed %d", rc);
4661                 return rc;
4662             }
4663 
4664             rc = declareSnapshotStreams();
4665             if (NO_ERROR != rc) {
4666                 LOGE("RAW stream info configuration failed %d", rc);
4667                 return rc;
4668             }
4669 
4670             rc = addChannel(QCAMERA_CH_TYPE_RAW);
4671             if (rc == NO_ERROR) {
4672                 // start postprocessor
4673                 if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
4674                     LOGE("Reprocess Deferred work failed");
4675                     return UNKNOWN_ERROR;
4676                 }
4677 
4678                 rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]);
4679                 if (rc != NO_ERROR) {
4680                     LOGE("cannot start postprocessor");
4681                     delChannel(QCAMERA_CH_TYPE_RAW);
4682                     return rc;
4683                 }
4684 
4685                 rc = startChannel(QCAMERA_CH_TYPE_RAW);
4686                 if (rc != NO_ERROR) {
4687                     LOGE("cannot start raw channel");
4688                     m_postprocessor.stop();
4689                     delChannel(QCAMERA_CH_TYPE_RAW);
4690                     return rc;
4691                 }
4692             } else {
4693                 LOGE("cannot add raw channel");
4694                 return rc;
4695             }
4696         }
4697     }
4698 
4699     //When take picture, stop sending preview callbacks to APP
4700     m_stateMachine.setPreviewCallbackNeeded(false);
4701     LOGI("X rc = %d", rc);
4702     return rc;
4703 }
4704 
4705 /*===========================================================================
4706  * FUNCTION   : configureOnlineRotation
4707  *
4708  * DESCRIPTION: Configure backend with expected rotation for snapshot stream
4709  *
4710  * PARAMETERS :
4711  *    @ch     : Channel containing a snapshot stream
4712  *
4713  * RETURN     : int32_t type of status
4714  *              NO_ERROR  -- success
4715  *              none-zero failure code
4716  *==========================================================================*/
configureOnlineRotation(QCameraChannel & ch)4717 int32_t QCamera2HardwareInterface::configureOnlineRotation(QCameraChannel &ch)
4718 {
4719     int rc = NO_ERROR;
4720     uint32_t streamId = 0;
4721     QCameraStream *pStream = NULL;
4722 
4723     for (uint8_t i = 0; i < ch.getNumOfStreams(); i++) {
4724         QCameraStream *stream = ch.getStreamByIndex(i);
4725         if ((NULL != stream) &&
4726                 ((CAM_STREAM_TYPE_SNAPSHOT == stream->getMyType())
4727                 || (CAM_STREAM_TYPE_RAW == stream->getMyType()))) {
4728             pStream = stream;
4729             break;
4730         }
4731     }
4732 
4733     if (NULL == pStream) {
4734         LOGE("No snapshot stream found!");
4735         return BAD_VALUE;
4736     }
4737 
4738     streamId = pStream->getMyServerID();
4739     // Update online rotation configuration
4740     rc = mParameters.addOnlineRotation(mParameters.getJpegRotation(), streamId,
4741             mParameters.getDeviceRotation());
4742     if (rc != NO_ERROR) {
4743         LOGE("addOnlineRotation failed %d", rc);
4744         return rc;
4745     }
4746 
4747     return rc;
4748 }
4749 
4750 /*===========================================================================
4751  * FUNCTION   : declareSnapshotStreams
4752  *
4753  * DESCRIPTION: Configure backend with expected snapshot streams
4754  *
4755  * PARAMETERS : none
4756  *
4757  * RETURN     : int32_t type of status
4758  *              NO_ERROR  -- success
4759  *              none-zero failure code
4760  *==========================================================================*/
declareSnapshotStreams()4761 int32_t QCamera2HardwareInterface::declareSnapshotStreams()
4762 {
4763     int rc = NO_ERROR;
4764 
4765     // Update stream info configuration
4766     rc = mParameters.setStreamConfigure(true, mLongshotEnabled, false);
4767     if (rc != NO_ERROR) {
4768         LOGE("setStreamConfigure failed %d", rc);
4769         return rc;
4770     }
4771 
4772     return rc;
4773 }
4774 
4775 /*===========================================================================
4776  * FUNCTION   : longShot
4777  *
4778  * DESCRIPTION: Queue one more ZSL frame
4779  *              in the longshot pipe.
4780  *
4781  * PARAMETERS : none
4782  *
4783  * RETURN     : int32_t type of status
4784  *              NO_ERROR  -- success
4785  *              none-zero failure code
4786  *==========================================================================*/
longShot()4787 int32_t QCamera2HardwareInterface::longShot()
4788 {
4789     int32_t rc = NO_ERROR;
4790     uint8_t numSnapshots = mParameters.getNumOfSnapshots();
4791     QCameraPicChannel *pChannel = NULL;
4792 
4793     if (mParameters.isZSLMode()) {
4794         pChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
4795     } else {
4796         pChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_CAPTURE];
4797     }
4798 
4799     if (NULL != pChannel) {
4800         mm_camera_req_buf_t buf;
4801         memset(&buf, 0x0, sizeof(buf));
4802         buf.type = MM_CAMERA_REQ_SUPER_BUF;
4803         buf.num_buf_requested = numSnapshots;
4804         rc = pChannel->takePicture(&buf);
4805     } else {
4806         LOGE("Capture channel not initialized!");
4807         rc = NO_INIT;
4808         goto end;
4809     }
4810 
4811 end:
4812     return rc;
4813 }
4814 
4815 /*===========================================================================
4816  * FUNCTION   : stopCaptureChannel
4817  *
4818  * DESCRIPTION: Stops capture channel
4819  *
4820  * PARAMETERS :
4821  *   @destroy : Set to true to stop and delete camera channel.
4822  *              Set to false to only stop capture channel.
4823  *
4824  * RETURN     : int32_t type of status
4825  *              NO_ERROR  -- success
4826  *              none-zero failure code
4827  *==========================================================================*/
stopCaptureChannel(bool destroy)4828 int QCamera2HardwareInterface::stopCaptureChannel(bool destroy)
4829 {
4830     int rc = NO_ERROR;
4831     if (mParameters.isJpegPictureFormat() ||
4832         mParameters.isNV16PictureFormat() ||
4833         mParameters.isNV21PictureFormat()) {
4834         rc = stopChannel(QCAMERA_CH_TYPE_CAPTURE);
4835         if (destroy && (NO_ERROR == rc)) {
4836             // Destroy camera channel but dont release context
4837             waitDeferredWork(mJpegJob);
4838             rc = delChannel(QCAMERA_CH_TYPE_CAPTURE, false);
4839         }
4840     }
4841 
4842     return rc;
4843 }
4844 
4845 /*===========================================================================
4846  * FUNCTION   : cancelPicture
4847  *
4848  * DESCRIPTION: cancel picture impl
4849  *
4850  * PARAMETERS : none
4851  *
4852  * RETURN     : int32_t type of status
4853  *              NO_ERROR  -- success
4854  *              none-zero failure code
4855  *==========================================================================*/
cancelPicture()4856 int QCamera2HardwareInterface::cancelPicture()
4857 {
4858     waitDeferredWork(mReprocJob);
4859     waitDeferredWork(mJpegJob);
4860 
4861     //stop post processor
4862     m_postprocessor.stop();
4863 
4864     unconfigureAdvancedCapture();
4865     LOGH("Enable display frames again");
4866     setDisplaySkip(FALSE);
4867 
4868     if (!mLongshotEnabled) {
4869         m_perfLock.lock_rel();
4870     }
4871 
4872     if (mParameters.isZSLMode()) {
4873         QCameraPicChannel *pPicChannel = NULL;
4874         if (mParameters.getofflineRAW()) {
4875             pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_RAW];
4876         } else {
4877             pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
4878         }
4879         if (NULL != pPicChannel) {
4880             pPicChannel->cancelPicture();
4881             stopRAWChannel();
4882             stopAdvancedCapture(pPicChannel);
4883         }
4884     } else {
4885 
4886         // normal capture case
4887         if (mParameters.isJpegPictureFormat() ||
4888             mParameters.isNV16PictureFormat() ||
4889             mParameters.isNV21PictureFormat()) {
4890             stopChannel(QCAMERA_CH_TYPE_CAPTURE);
4891             delChannel(QCAMERA_CH_TYPE_CAPTURE);
4892         } else {
4893             stopChannel(QCAMERA_CH_TYPE_RAW);
4894             delChannel(QCAMERA_CH_TYPE_RAW);
4895         }
4896     }
4897 
4898     return NO_ERROR;
4899 }
4900 
4901 /*===========================================================================
4902  * FUNCTION   : captureDone
4903  *
4904  * DESCRIPTION: Function called when the capture is completed before encoding
4905  *
4906  * PARAMETERS : none
4907  *
4908  * RETURN     : none
4909  *==========================================================================*/
captureDone()4910 void QCamera2HardwareInterface::captureDone()
4911 {
4912     qcamera_sm_internal_evt_payload_t *payload =
4913        (qcamera_sm_internal_evt_payload_t *)
4914        malloc(sizeof(qcamera_sm_internal_evt_payload_t));
4915     if (NULL != payload) {
4916         memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
4917         payload->evt_type = QCAMERA_INTERNAL_EVT_ZSL_CAPTURE_DONE;
4918         int32_t rc = processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
4919         if (rc != NO_ERROR) {
4920             LOGE("processEvt ZSL capture done failed");
4921             free(payload);
4922             payload = NULL;
4923         }
4924     } else {
4925         LOGE("No memory for ZSL capture done event");
4926     }
4927 }
4928 
4929 /*===========================================================================
4930  * FUNCTION   : Live_Snapshot_thread
4931  *
4932  * DESCRIPTION: Seperate thread for taking live snapshot during recording
4933  *
4934  * PARAMETERS : @data - pointer to QCamera2HardwareInterface class object
4935  *
4936  * RETURN     : none
4937  *==========================================================================*/
Live_Snapshot_thread(void * data)4938 void* Live_Snapshot_thread (void* data)
4939 {
4940 
4941     QCamera2HardwareInterface *hw = reinterpret_cast<QCamera2HardwareInterface *>(data);
4942     if (!hw) {
4943         LOGE("take_picture_thread: NULL camera device");
4944         return (void *)BAD_VALUE;
4945     }
4946     hw->takeLiveSnapshot_internal();
4947     return (void* )NULL;
4948 }
4949 
4950 /*===========================================================================
4951  * FUNCTION   : Int_Pic_thread
4952  *
4953  * DESCRIPTION: Seperate thread for taking snapshot triggered by camera backend
4954  *
4955  * PARAMETERS : @data - pointer to QCamera2HardwareInterface class object
4956  *
4957  * RETURN     : none
4958  *==========================================================================*/
Int_Pic_thread(void * data)4959 void* Int_Pic_thread (void* data)
4960 {
4961     int rc = NO_ERROR;
4962 
4963     QCamera2HardwareInterface *hw = reinterpret_cast<QCamera2HardwareInterface *>(data);
4964 
4965     if (!hw) {
4966         LOGE("take_picture_thread: NULL camera device");
4967         return (void *)BAD_VALUE;
4968     }
4969 
4970     bool JpegMemOpt = false;
4971     char raw_format[PROPERTY_VALUE_MAX];
4972 
4973     memset(raw_format, 0, sizeof(raw_format));
4974 
4975     rc = hw->takeBackendPic_internal(&JpegMemOpt, &raw_format[0]);
4976     if (rc == NO_ERROR) {
4977         hw->checkIntPicPending(JpegMemOpt, &raw_format[0]);
4978     } else {
4979         //Snapshot attempt not successful, we need to do cleanup here
4980         hw->clearIntPendingEvents();
4981     }
4982 
4983     return (void* )NULL;
4984 }
4985 
4986 /*===========================================================================
4987  * FUNCTION   : takeLiveSnapshot
4988  *
4989  * DESCRIPTION: take live snapshot during recording
4990  *
4991  * PARAMETERS : none
4992  *
4993  * RETURN     : int32_t type of status
4994  *              NO_ERROR  -- success
4995  *              none-zero failure code
4996  *==========================================================================*/
takeLiveSnapshot()4997 int QCamera2HardwareInterface::takeLiveSnapshot()
4998 {
4999     int rc = NO_ERROR;
5000     rc= pthread_create(&mLiveSnapshotThread, NULL, Live_Snapshot_thread, (void *) this);
5001     if (!rc) {
5002         pthread_setname_np(mLiveSnapshotThread, "CAM_liveSnap");
5003     }
5004     return rc;
5005 }
5006 
5007 /*===========================================================================
5008  * FUNCTION   : takePictureInternal
5009  *
5010  * DESCRIPTION: take snapshot triggered by backend
5011  *
5012  * PARAMETERS : none
5013  *
5014  * RETURN     : int32_t type of status
5015  *              NO_ERROR  -- success
5016  *              none-zero failure code
5017  *==========================================================================*/
takePictureInternal()5018 int QCamera2HardwareInterface::takePictureInternal()
5019 {
5020     int rc = NO_ERROR;
5021     rc= pthread_create(&mIntPicThread, NULL, Int_Pic_thread, (void *) this);
5022     if (!rc) {
5023         pthread_setname_np(mIntPicThread, "CAM_IntPic");
5024     }
5025     return rc;
5026 }
5027 
5028 /*===========================================================================
5029  * FUNCTION   : checkIntPicPending
5030  *
5031  * DESCRIPTION: timed wait for jpeg completion event, and send
5032  *                        back completion event to backend
5033  *
5034  * PARAMETERS : none
5035  *
5036  * RETURN     : none
5037  *==========================================================================*/
checkIntPicPending(bool JpegMemOpt,char * raw_format)5038 void QCamera2HardwareInterface::checkIntPicPending(bool JpegMemOpt, char *raw_format)
5039 {
5040     bool bSendToBackend = true;
5041     cam_int_evt_params_t params;
5042     int rc = NO_ERROR;
5043 
5044     struct timespec   ts;
5045     struct timeval    tp;
5046     gettimeofday(&tp, NULL);
5047     ts.tv_sec  = tp.tv_sec + 5;
5048     ts.tv_nsec = tp.tv_usec * 1000;
5049 
5050     if (true == m_bIntJpegEvtPending ||
5051         (true == m_bIntRawEvtPending)) {
5052         //Waiting in HAL for snapshot taken notification
5053         pthread_mutex_lock(&m_int_lock);
5054         rc = pthread_cond_timedwait(&m_int_cond, &m_int_lock, &ts);
5055         if (ETIMEDOUT == rc || 0x0 == m_BackendFileName[0]) {
5056             //Hit a timeout, or some spurious activity
5057             bSendToBackend = false;
5058         }
5059 
5060         if (true == m_bIntJpegEvtPending) {
5061             params.event_type = 0;
5062             mParameters.getStreamFormat(CAM_STREAM_TYPE_SNAPSHOT, params.picture_format);
5063         } else if (true == m_bIntRawEvtPending) {
5064             params.event_type = 1;
5065             mParameters.getStreamFormat(CAM_STREAM_TYPE_RAW, params.picture_format);
5066         }
5067         pthread_mutex_unlock(&m_int_lock);
5068 
5069         if (true == m_bIntJpegEvtPending) {
5070             //Attempting to restart preview after taking JPEG snapshot
5071             lockAPI();
5072             rc = processAPI(QCAMERA_SM_EVT_SNAPSHOT_DONE, NULL);
5073             unlockAPI();
5074             m_postprocessor.setJpegMemOpt(JpegMemOpt);
5075         } else if (true == m_bIntRawEvtPending) {
5076             //Attempting to restart preview after taking RAW snapshot
5077             stopChannel(QCAMERA_CH_TYPE_RAW);
5078             delChannel(QCAMERA_CH_TYPE_RAW);
5079             //restoring the old raw format
5080             property_set("persist.camera.raw.format", raw_format);
5081         }
5082 
5083         if (true == bSendToBackend) {
5084             //send event back to server with the file path
5085             params.dim = m_postprocessor.m_dst_dim;
5086             memcpy(&params.path[0], &m_BackendFileName[0], QCAMERA_MAX_FILEPATH_LENGTH);
5087             memset(&m_BackendFileName[0], 0x0, QCAMERA_MAX_FILEPATH_LENGTH);
5088             params.size = mBackendFileSize;
5089             rc = mParameters.setIntEvent(params);
5090         }
5091 
5092         clearIntPendingEvents();
5093     }
5094 
5095     return;
5096 }
5097 
5098 /*===========================================================================
5099  * FUNCTION   : takeBackendPic_internal
5100  *
5101  * DESCRIPTION: take snapshot triggered by backend
5102  *
5103  * PARAMETERS : none
5104  *
5105  * RETURN     : int32_t type of status
5106  *              NO_ERROR  -- success
5107  *              none-zero failure code
5108  *==========================================================================*/
takeBackendPic_internal(bool * JpegMemOpt,char * raw_format)5109 int QCamera2HardwareInterface::takeBackendPic_internal(bool *JpegMemOpt, char *raw_format)
5110 {
5111     int rc = NO_ERROR;
5112     qcamera_api_result_t apiResult;
5113 
5114     lockAPI();
5115     //Set rotation value from user settings as Jpeg rotation
5116     //to configure back-end modules.
5117     mParameters.setJpegRotation(mParameters.getRotation());
5118 
5119     setRetroPicture(0);
5120     /* Prepare snapshot in case LED needs to be flashed */
5121     if (mFlashNeeded == 1 || mParameters.isChromaFlashEnabled()) {
5122         // Start Preparing for normal Frames
5123         LOGH("Start Prepare Snapshot");
5124         /* Prepare snapshot in case LED needs to be flashed */
5125         rc = processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL);
5126         if (rc == NO_ERROR) {
5127             waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, &apiResult);
5128             rc = apiResult.status;
5129         }
5130         LOGH("Prep Snapshot done rc = %d", rc);
5131         mPrepSnapRun = true;
5132     }
5133     unlockAPI();
5134 
5135     if (true == m_bIntJpegEvtPending) {
5136         //Attempting to take JPEG snapshot
5137         if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
5138             LOGE("Init PProc Deferred work failed");
5139             return UNKNOWN_ERROR;
5140         }
5141         *JpegMemOpt = m_postprocessor.getJpegMemOpt();
5142         m_postprocessor.setJpegMemOpt(false);
5143 
5144         /* capture */
5145         lockAPI();
5146         LOGH("Capturing internal snapshot");
5147         rc = processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL);
5148         if (rc == NO_ERROR) {
5149             waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult);
5150             rc = apiResult.status;
5151         }
5152         unlockAPI();
5153     } else if (true == m_bIntRawEvtPending) {
5154         //Attempting to take RAW snapshot
5155         (void)JpegMemOpt;
5156         stopPreview();
5157 
5158         //getting the existing raw format type
5159         property_get("persist.camera.raw.format", raw_format, "17");
5160         //setting it to a default know value for this task
5161         property_set("persist.camera.raw.format", "18");
5162 
5163         rc = addChannel(QCAMERA_CH_TYPE_RAW);
5164         if (rc == NO_ERROR) {
5165             // start postprocessor
5166             if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
5167                 LOGE("Init PProc Deferred work failed");
5168                 return UNKNOWN_ERROR;
5169             }
5170             rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]);
5171             if (rc != NO_ERROR) {
5172                 LOGE("cannot start postprocessor");
5173                 delChannel(QCAMERA_CH_TYPE_RAW);
5174                 return rc;
5175             }
5176 
5177             rc = startChannel(QCAMERA_CH_TYPE_RAW);
5178             if (rc != NO_ERROR) {
5179                 LOGE("cannot start raw channel");
5180                 m_postprocessor.stop();
5181                 delChannel(QCAMERA_CH_TYPE_RAW);
5182                 return rc;
5183             }
5184         } else {
5185             LOGE("cannot add raw channel");
5186             return rc;
5187         }
5188     }
5189 
5190     return rc;
5191 }
5192 
5193 /*===========================================================================
5194  * FUNCTION   : clearIntPendingEvents
5195  *
5196  * DESCRIPTION: clear internal pending events pertaining to backend
5197  *                        snapshot requests
5198  *
5199  * PARAMETERS : none
5200  *
5201  * RETURN     : int32_t type of status
5202  *              NO_ERROR  -- success
5203  *              none-zero failure code
5204  *==========================================================================*/
clearIntPendingEvents()5205 void QCamera2HardwareInterface::clearIntPendingEvents()
5206 {
5207     int rc = NO_ERROR;
5208 
5209     if (true == m_bIntRawEvtPending) {
5210         preparePreview();
5211         startPreview();
5212     }
5213     if (true == m_bIntJpegEvtPending) {
5214         if (false == mParameters.isZSLMode()) {
5215             lockAPI();
5216             rc = processAPI(QCAMERA_SM_EVT_START_PREVIEW, NULL);
5217             unlockAPI();
5218         }
5219     }
5220 
5221     pthread_mutex_lock(&m_int_lock);
5222     if (true == m_bIntJpegEvtPending) {
5223         m_bIntJpegEvtPending = false;
5224     } else if (true == m_bIntRawEvtPending) {
5225         m_bIntRawEvtPending = false;
5226     }
5227     pthread_mutex_unlock(&m_int_lock);
5228     return;
5229 }
5230 
5231 /*===========================================================================
5232  * FUNCTION   : takeLiveSnapshot_internal
5233  *
5234  * DESCRIPTION: take live snapshot during recording
5235  *
5236  * PARAMETERS : none
5237  *
5238  * RETURN     : int32_t type of status
5239  *              NO_ERROR  -- success
5240  *              none-zero failure code
5241  *==========================================================================*/
takeLiveSnapshot_internal()5242 int QCamera2HardwareInterface::takeLiveSnapshot_internal()
5243 {
5244     int rc = NO_ERROR;
5245 
5246     QCameraChannel *pChannel = NULL;
5247 
5248     //Set rotation value from user settings as Jpeg rotation
5249     //to configure back-end modules.
5250     mParameters.setJpegRotation(mParameters.getRotation());
5251 
5252     // Configure advanced capture
5253     rc = configureAdvancedCapture();
5254     if (rc != NO_ERROR) {
5255         LOGE("Unsupported capture call");
5256         goto end;
5257     }
5258 
5259     if (isLowPowerMode()) {
5260         pChannel = m_channels[QCAMERA_CH_TYPE_VIDEO];
5261     } else {
5262         pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
5263     }
5264 
5265     if (NULL == pChannel) {
5266         LOGE("Snapshot/Video channel not initialized");
5267         rc = NO_INIT;
5268         goto end;
5269     }
5270 
5271     DeferWorkArgs args;
5272     memset(&args, 0, sizeof(DeferWorkArgs));
5273 
5274     args.pprocArgs = pChannel;
5275 
5276     // No need to wait for mInitPProcJob here, because it was
5277     // queued in startPreview, and will definitely be processed before
5278     // mReprocJob can begin.
5279     mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START,
5280             args);
5281     if (mReprocJob == 0) {
5282         LOGE("Failed to queue CMD_DEF_PPROC_START");
5283         rc = -ENOMEM;
5284         goto end;
5285     }
5286 
5287     // Create JPEG session
5288     mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION,
5289             args);
5290     if (mJpegJob == 0) {
5291         LOGE("Failed to queue CREATE_JPEG_SESSION");
5292         if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5293             LOGE("Reprocess Deferred work was failed");
5294         }
5295         m_postprocessor.stop();
5296         rc = -ENOMEM;
5297         goto end;
5298     }
5299 
5300     if (isLowPowerMode()) {
5301         mm_camera_req_buf_t buf;
5302         memset(&buf, 0x0, sizeof(buf));
5303         buf.type = MM_CAMERA_REQ_SUPER_BUF;
5304         buf.num_buf_requested = 1;
5305         rc = ((QCameraVideoChannel*)pChannel)->takePicture(&buf);
5306         goto end;
5307     }
5308 
5309     //Disable reprocess for 4K liveshot case
5310     if (!mParameters.is4k2kVideoResolution()) {
5311         rc = configureOnlineRotation(*m_channels[QCAMERA_CH_TYPE_SNAPSHOT]);
5312         if (rc != NO_ERROR) {
5313             LOGE("online rotation failed");
5314             if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5315                 LOGE("Reprocess Deferred work was failed");
5316             }
5317             if (NO_ERROR != waitDeferredWork(mJpegJob)) {
5318                 LOGE("Jpeg Deferred work was failed");
5319             }
5320             m_postprocessor.stop();
5321             return rc;
5322         }
5323     }
5324 
5325     if ((NULL != pChannel) && (mParameters.isTNRSnapshotEnabled())) {
5326         QCameraStream *pStream = NULL;
5327         for (uint32_t i = 0 ; i < pChannel->getNumOfStreams(); i++ ) {
5328             pStream = pChannel->getStreamByIndex(i);
5329             if ((NULL != pStream) &&
5330                     (CAM_STREAM_TYPE_SNAPSHOT == pStream->getMyType())) {
5331                 break;
5332             }
5333         }
5334         if (pStream != NULL) {
5335             LOGD("REQUEST_FRAMES event for TNR snapshot");
5336             cam_stream_parm_buffer_t param;
5337             memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
5338             param.type = CAM_STREAM_PARAM_TYPE_REQUEST_FRAMES;
5339             param.frameRequest.enableStream = 1;
5340             rc = pStream->setParameter(param);
5341             if (rc != NO_ERROR) {
5342                 LOGE("Stream Event REQUEST_FRAMES failed");
5343             }
5344             goto end;
5345         }
5346     }
5347 
5348     // start snapshot channel
5349     if ((rc == NO_ERROR) && (NULL != pChannel)) {
5350         // Do not link metadata stream for 4K2k resolution
5351         // as CPP processing would be done on snapshot stream and not
5352         // reprocess stream
5353         if (!mParameters.is4k2kVideoResolution()) {
5354             // Find and try to link a metadata stream from preview channel
5355             QCameraChannel *pMetaChannel = NULL;
5356             QCameraStream *pMetaStream = NULL;
5357             QCameraStream *pPreviewStream = NULL;
5358 
5359             if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
5360                 pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
5361                 uint32_t streamNum = pMetaChannel->getNumOfStreams();
5362                 QCameraStream *pStream = NULL;
5363                 for (uint32_t i = 0 ; i < streamNum ; i++ ) {
5364                     pStream = pMetaChannel->getStreamByIndex(i);
5365                     if (NULL != pStream) {
5366                         if (CAM_STREAM_TYPE_METADATA == pStream->getMyType()) {
5367                             pMetaStream = pStream;
5368                         } else if (CAM_STREAM_TYPE_PREVIEW == pStream->getMyType()) {
5369                             pPreviewStream = pStream;
5370                         }
5371                     }
5372                 }
5373             }
5374 
5375             if ((NULL != pMetaChannel) && (NULL != pMetaStream)) {
5376                 rc = pChannel->linkStream(pMetaChannel, pMetaStream);
5377                 if (NO_ERROR != rc) {
5378                     LOGE("Metadata stream link failed %d", rc);
5379                 }
5380             }
5381             if ((NULL != pMetaChannel) && (NULL != pPreviewStream)) {
5382                 rc = pChannel->linkStream(pMetaChannel, pPreviewStream);
5383                 if (NO_ERROR != rc) {
5384                     LOGE("Preview stream link failed %d", rc);
5385                 }
5386             }
5387         }
5388         rc = pChannel->start();
5389     }
5390 
5391 end:
5392     if (rc != NO_ERROR) {
5393         rc = processAPI(QCAMERA_SM_EVT_CANCEL_PICTURE, NULL);
5394         rc = sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
5395     }
5396     return rc;
5397 }
5398 
5399 /*===========================================================================
5400  * FUNCTION   : cancelLiveSnapshot
5401  *
5402  * DESCRIPTION: cancel current live snapshot request
5403  *
5404  * PARAMETERS : none
5405  *
5406  * RETURN     : int32_t type of status
5407  *              NO_ERROR  -- success
5408  *              none-zero failure code
5409  *==========================================================================*/
cancelLiveSnapshot()5410 int QCamera2HardwareInterface::cancelLiveSnapshot()
5411 {
5412     int rc = NO_ERROR;
5413 
5414     unconfigureAdvancedCapture();
5415     LOGH("Enable display frames again");
5416     setDisplaySkip(FALSE);
5417 
5418     if (!mLongshotEnabled) {
5419         m_perfLock.lock_rel();
5420     }
5421 
5422     if (mLiveSnapshotThread != 0) {
5423         pthread_join(mLiveSnapshotThread,NULL);
5424         mLiveSnapshotThread = 0;
5425     }
5426 
5427     //stop post processor
5428     m_postprocessor.stop();
5429 
5430     // stop snapshot channel
5431     if (!mParameters.isTNRSnapshotEnabled()) {
5432         rc = stopChannel(QCAMERA_CH_TYPE_SNAPSHOT);
5433     } else {
5434         QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
5435         if (NULL != pChannel) {
5436             QCameraStream *pStream = NULL;
5437             for (uint32_t i = 0 ; i < pChannel->getNumOfStreams(); i++ ) {
5438                 pStream = pChannel->getStreamByIndex(i);
5439                 if ((NULL != pStream) &&
5440                         (CAM_STREAM_TYPE_SNAPSHOT ==
5441                         pStream->getMyType())) {
5442                     break;
5443                 }
5444             }
5445             if (pStream != NULL) {
5446                 LOGD("REQUEST_FRAMES event for TNR snapshot");
5447                 cam_stream_parm_buffer_t param;
5448                 memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
5449                 param.type = CAM_STREAM_PARAM_TYPE_REQUEST_FRAMES;
5450                 param.frameRequest.enableStream = 0;
5451                 rc = pStream->setParameter(param);
5452                 if (rc != NO_ERROR) {
5453                     LOGE("Stream Event REQUEST_FRAMES failed");
5454                 }
5455             }
5456         }
5457     }
5458 
5459     return rc;
5460 }
5461 
5462 /*===========================================================================
5463  * FUNCTION   : putParameters
5464  *
5465  * DESCRIPTION: put parameters string impl
5466  *
5467  * PARAMETERS :
5468  *   @parms   : parameters string to be released
5469  *
5470  * RETURN     : int32_t type of status
5471  *              NO_ERROR  -- success
5472  *              none-zero failure code
5473  *==========================================================================*/
putParameters(char * parms)5474 int QCamera2HardwareInterface::putParameters(char *parms)
5475 {
5476     free(parms);
5477     return NO_ERROR;
5478 }
5479 
5480 /*===========================================================================
5481  * FUNCTION   : sendCommand
5482  *
5483  * DESCRIPTION: send command impl
5484  *
5485  * PARAMETERS :
5486  *   @command : command to be executed
5487  *   @arg1    : optional argument 1
5488  *   @arg2    : optional argument 2
5489  *
5490  * RETURN     : int32_t type of status
5491  *              NO_ERROR  -- success
5492  *              none-zero failure code
5493  *==========================================================================*/
sendCommand(int32_t command,__unused int32_t & arg1,__unused int32_t & arg2)5494 int QCamera2HardwareInterface::sendCommand(int32_t command,
5495         __unused int32_t &arg1, __unused int32_t &arg2)
5496 {
5497     int rc = NO_ERROR;
5498 
5499     switch (command) {
5500 #ifndef VANILLA_HAL
5501     case CAMERA_CMD_LONGSHOT_ON:
5502         m_perfLock.lock_acq();
5503         arg1 = arg2 = 0;
5504         // Longshot can only be enabled when image capture
5505         // is not active.
5506         if ( !m_stateMachine.isCaptureRunning() ) {
5507             LOGI("Longshot Enabled");
5508             mLongshotEnabled = true;
5509             rc = mParameters.setLongshotEnable(mLongshotEnabled);
5510 
5511             // Due to recent buffer count optimizations
5512             // ZSL might run with considerably less buffers
5513             // when not in longshot mode. Preview needs to
5514             // restart in this case.
5515             if (isZSLMode() && m_stateMachine.isPreviewRunning()) {
5516                 QCameraChannel *pChannel = NULL;
5517                 QCameraStream *pSnapStream = NULL;
5518                 pChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
5519                 if (NULL != pChannel) {
5520                     QCameraStream *pStream = NULL;
5521                     for (uint32_t i = 0; i < pChannel->getNumOfStreams(); i++) {
5522                         pStream = pChannel->getStreamByIndex(i);
5523                         if (pStream != NULL) {
5524                             if (pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT)) {
5525                                 pSnapStream = pStream;
5526                                 break;
5527                             }
5528                         }
5529                     }
5530                     if (NULL != pSnapStream) {
5531                         uint8_t required = 0;
5532                         required = getBufNumRequired(CAM_STREAM_TYPE_SNAPSHOT);
5533                         if (pSnapStream->getBufferCount() < required) {
5534                             // We restart here, to reset the FPS and no
5535                             // of buffers as per the requirement of longshot usecase.
5536                             arg1 = QCAMERA_SM_EVT_RESTART_PERVIEW;
5537                             if (getRelatedCamSyncInfo()->sync_control ==
5538                                     CAM_SYNC_RELATED_SENSORS_ON) {
5539                                 arg2 = QCAMERA_SM_EVT_DELAYED_RESTART;
5540                             }
5541                         }
5542                     }
5543                 }
5544             }
5545             //
5546             mPrepSnapRun = false;
5547             mCACDoneReceived = FALSE;
5548         } else {
5549             rc = NO_INIT;
5550         }
5551         break;
5552     case CAMERA_CMD_LONGSHOT_OFF:
5553         m_perfLock.lock_rel();
5554         if ( mLongshotEnabled && m_stateMachine.isCaptureRunning() ) {
5555             cancelPicture();
5556             processEvt(QCAMERA_SM_EVT_SNAPSHOT_DONE, NULL);
5557             QCameraChannel *pZSLChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
5558             if (isZSLMode() && (NULL != pZSLChannel) && mPrepSnapRun) {
5559                 mCameraHandle->ops->stop_zsl_snapshot(
5560                         mCameraHandle->camera_handle,
5561                         pZSLChannel->getMyHandle());
5562             }
5563         }
5564         mPrepSnapRun = false;
5565         LOGI("Longshot Disabled");
5566         mLongshotEnabled = false;
5567         rc = mParameters.setLongshotEnable(mLongshotEnabled);
5568         mCACDoneReceived = FALSE;
5569         break;
5570     case CAMERA_CMD_HISTOGRAM_ON:
5571     case CAMERA_CMD_HISTOGRAM_OFF:
5572         rc = setHistogram(command == CAMERA_CMD_HISTOGRAM_ON? true : false);
5573         LOGH("Histogram -> %s",
5574               mParameters.isHistogramEnabled() ? "Enabled" : "Disabled");
5575         break;
5576 #endif
5577     case CAMERA_CMD_START_FACE_DETECTION:
5578     case CAMERA_CMD_STOP_FACE_DETECTION:
5579         mParameters.setFaceDetectionOption(command == CAMERA_CMD_START_FACE_DETECTION? true : false);
5580         rc = setFaceDetection(command == CAMERA_CMD_START_FACE_DETECTION? true : false);
5581         LOGH("FaceDetection -> %s",
5582               mParameters.isFaceDetectionEnabled() ? "Enabled" : "Disabled");
5583         break;
5584 #ifndef VANILLA_HAL
5585     case CAMERA_CMD_HISTOGRAM_SEND_DATA:
5586 #endif
5587     default:
5588         rc = NO_ERROR;
5589         break;
5590     }
5591     return rc;
5592 }
5593 
5594 /*===========================================================================
5595  * FUNCTION   : registerFaceImage
5596  *
5597  * DESCRIPTION: register face image impl
5598  *
5599  * PARAMETERS :
5600  *   @img_ptr : ptr to image buffer
5601  *   @config  : ptr to config struct about input image info
5602  *   @faceID  : [OUT] face ID to uniquely identifiy the registered face image
5603  *
5604  * RETURN     : int32_t type of status
5605  *              NO_ERROR  -- success
5606  *              none-zero failure code
5607  *==========================================================================*/
registerFaceImage(void * img_ptr,cam_pp_offline_src_config_t * config,int32_t & faceID)5608 int QCamera2HardwareInterface::registerFaceImage(void *img_ptr,
5609                                                  cam_pp_offline_src_config_t *config,
5610                                                  int32_t &faceID)
5611 {
5612     int rc = NO_ERROR;
5613     faceID = -1;
5614 
5615     if (img_ptr == NULL || config == NULL) {
5616         LOGE("img_ptr or config is NULL");
5617         return BAD_VALUE;
5618     }
5619 
5620     // allocate ion memory for source image
5621     QCameraHeapMemory *imgBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
5622     if (imgBuf == NULL) {
5623         LOGE("Unable to new heap memory obj for image buf");
5624         return NO_MEMORY;
5625     }
5626 
5627     rc = imgBuf->allocate(1, config->input_buf_planes.plane_info.frame_len, NON_SECURE);
5628     if (rc < 0) {
5629         LOGE("Unable to allocate heap memory for image buf");
5630         delete imgBuf;
5631         return NO_MEMORY;
5632     }
5633 
5634     void *pBufPtr = imgBuf->getPtr(0);
5635     if (pBufPtr == NULL) {
5636         LOGE("image buf is NULL");
5637         imgBuf->deallocate();
5638         delete imgBuf;
5639         return NO_MEMORY;
5640     }
5641     memcpy(pBufPtr, img_ptr, config->input_buf_planes.plane_info.frame_len);
5642 
5643     cam_pp_feature_config_t pp_feature;
5644     memset(&pp_feature, 0, sizeof(cam_pp_feature_config_t));
5645     pp_feature.feature_mask = CAM_QCOM_FEATURE_REGISTER_FACE;
5646     QCameraReprocessChannel *pChannel =
5647         addOfflineReprocChannel(*config, pp_feature, NULL, NULL);
5648 
5649     if (pChannel == NULL) {
5650         LOGE("fail to add offline reprocess channel");
5651         imgBuf->deallocate();
5652         delete imgBuf;
5653         return UNKNOWN_ERROR;
5654     }
5655 
5656     rc = pChannel->start();
5657     if (rc != NO_ERROR) {
5658         LOGE("Cannot start reprocess channel");
5659         imgBuf->deallocate();
5660         delete imgBuf;
5661         delete pChannel;
5662         return rc;
5663     }
5664 
5665     ssize_t bufSize = imgBuf->getSize(0);
5666     if (BAD_INDEX != bufSize) {
5667         rc = pChannel->doReprocess(imgBuf->getFd(0), (size_t)bufSize, faceID);
5668     } else {
5669         LOGE("Failed to retrieve buffer size (bad index)");
5670         return UNKNOWN_ERROR;
5671     }
5672 
5673     // done with register face image, free imgbuf and delete reprocess channel
5674     imgBuf->deallocate();
5675     delete imgBuf;
5676     imgBuf = NULL;
5677     pChannel->stop();
5678     delete pChannel;
5679     pChannel = NULL;
5680 
5681     return rc;
5682 }
5683 
5684 /*===========================================================================
5685  * FUNCTION   : release
5686  *
5687  * DESCRIPTION: release camera resource impl
5688  *
5689  * PARAMETERS : none
5690  *
5691  * RETURN     : int32_t type of status
5692  *              NO_ERROR  -- success
5693  *              none-zero failure code
5694  *==========================================================================*/
release()5695 int QCamera2HardwareInterface::release()
5696 {
5697     // stop and delete all channels
5698     for (int i = 0; i <QCAMERA_CH_TYPE_MAX ; i++) {
5699         if (m_channels[i] != NULL) {
5700             stopChannel((qcamera_ch_type_enum_t)i);
5701             delChannel((qcamera_ch_type_enum_t)i);
5702         }
5703     }
5704 
5705     return NO_ERROR;
5706 }
5707 
5708 /*===========================================================================
5709  * FUNCTION   : dump
5710  *
5711  * DESCRIPTION: camera status dump impl
5712  *
5713  * PARAMETERS :
5714  *   @fd      : fd for the buffer to be dumped with camera status
5715  *
5716  * RETURN     : int32_t type of status
5717  *              NO_ERROR  -- success
5718  *              none-zero failure code
5719  *==========================================================================*/
dump(int fd)5720 int QCamera2HardwareInterface::dump(int fd)
5721 {
5722     dprintf(fd, "\n Camera HAL information Begin \n");
5723     dprintf(fd, "Camera ID: %d \n", mCameraId);
5724     dprintf(fd, "StoreMetaDataInFrame: %d \n", mStoreMetaDataInFrame);
5725     dprintf(fd, "\n Configuration: %s", mParameters.dump().string());
5726     dprintf(fd, "\n State Information: %s", m_stateMachine.dump().string());
5727     dprintf(fd, "\n Camera HAL information End \n");
5728 
5729     /* send UPDATE_DEBUG_LEVEL to the backend so that they can read the
5730        debug level property */
5731     mParameters.updateDebugLevel();
5732     return NO_ERROR;
5733 }
5734 
5735 /*===========================================================================
5736  * FUNCTION   : processAPI
5737  *
5738  * DESCRIPTION: process API calls from upper layer
5739  *
5740  * PARAMETERS :
5741  *   @api         : API to be processed
5742  *   @api_payload : ptr to API payload if any
5743  *
5744  * RETURN     : int32_t type of status
5745  *              NO_ERROR  -- success
5746  *              none-zero failure code
5747  *==========================================================================*/
processAPI(qcamera_sm_evt_enum_t api,void * api_payload)5748 int QCamera2HardwareInterface::processAPI(qcamera_sm_evt_enum_t api, void *api_payload)
5749 {
5750     int ret = DEAD_OBJECT;
5751 
5752     if (m_smThreadActive) {
5753         ret = m_stateMachine.procAPI(api, api_payload);
5754     }
5755 
5756     return ret;
5757 }
5758 
5759 /*===========================================================================
5760  * FUNCTION   : processEvt
5761  *
5762  * DESCRIPTION: process Evt from backend via mm-camera-interface
5763  *
5764  * PARAMETERS :
5765  *   @evt         : event type to be processed
5766  *   @evt_payload : ptr to event payload if any
5767  *
5768  * RETURN     : int32_t type of status
5769  *              NO_ERROR  -- success
5770  *              none-zero failure code
5771  *==========================================================================*/
processEvt(qcamera_sm_evt_enum_t evt,void * evt_payload)5772 int QCamera2HardwareInterface::processEvt(qcamera_sm_evt_enum_t evt, void *evt_payload)
5773 {
5774     return m_stateMachine.procEvt(evt, evt_payload);
5775 }
5776 
5777 /*===========================================================================
5778  * FUNCTION   : processSyncEvt
5779  *
5780  * DESCRIPTION: process synchronous Evt from backend
5781  *
5782  * PARAMETERS :
5783  *   @evt         : event type to be processed
5784  *   @evt_payload : ptr to event payload if any
5785  *
5786  * RETURN     : int32_t type of status
5787  *              NO_ERROR  -- success
5788  *              none-zero failure code
5789  *==========================================================================*/
processSyncEvt(qcamera_sm_evt_enum_t evt,void * evt_payload)5790 int QCamera2HardwareInterface::processSyncEvt(qcamera_sm_evt_enum_t evt, void *evt_payload)
5791 {
5792     int rc = NO_ERROR;
5793 
5794     pthread_mutex_lock(&m_evtLock);
5795     rc =  processEvt(evt, evt_payload);
5796     if (rc == NO_ERROR) {
5797         memset(&m_evtResult, 0, sizeof(qcamera_api_result_t));
5798         while (m_evtResult.request_api != evt) {
5799             pthread_cond_wait(&m_evtCond, &m_evtLock);
5800         }
5801         rc =  m_evtResult.status;
5802     }
5803     pthread_mutex_unlock(&m_evtLock);
5804 
5805     return rc;
5806 }
5807 
5808 /*===========================================================================
5809  * FUNCTION   : evtHandle
5810  *
5811  * DESCRIPTION: Function registerd to mm-camera-interface to handle backend events
5812  *
5813  * PARAMETERS :
5814  *   @camera_handle : event type to be processed
5815  *   @evt           : ptr to event
5816  *   @user_data     : user data ptr
5817  *
5818  * RETURN     : none
5819  *==========================================================================*/
camEvtHandle(uint32_t,mm_camera_event_t * evt,void * user_data)5820 void QCamera2HardwareInterface::camEvtHandle(uint32_t /*camera_handle*/,
5821                                           mm_camera_event_t *evt,
5822                                           void *user_data)
5823 {
5824     QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)user_data;
5825     if (obj && evt) {
5826         mm_camera_event_t *payload =
5827             (mm_camera_event_t *)malloc(sizeof(mm_camera_event_t));
5828         if (NULL != payload) {
5829             *payload = *evt;
5830             //peek into the event, if this is an eztune event from server,
5831             //then we don't need to post it to the SM Qs, we shud directly
5832             //spawn a thread and get the job done (jpeg or raw snapshot)
5833             switch (payload->server_event_type) {
5834                 case CAM_EVENT_TYPE_INT_TAKE_JPEG:
5835                     //Received JPEG trigger from eztune
5836                     if (false == obj->m_bIntJpegEvtPending) {
5837                         pthread_mutex_lock(&obj->m_int_lock);
5838                         obj->m_bIntJpegEvtPending = true;
5839                         pthread_mutex_unlock(&obj->m_int_lock);
5840                         obj->takePictureInternal();
5841                     }
5842                     free(payload);
5843                     break;
5844                 case CAM_EVENT_TYPE_INT_TAKE_RAW:
5845                     //Received RAW trigger from eztune
5846                     if (false == obj->m_bIntRawEvtPending) {
5847                         pthread_mutex_lock(&obj->m_int_lock);
5848                         obj->m_bIntRawEvtPending = true;
5849                         pthread_mutex_unlock(&obj->m_int_lock);
5850                         obj->takePictureInternal();
5851                     }
5852                     free(payload);
5853                     break;
5854                 case CAM_EVENT_TYPE_DAEMON_DIED:
5855                     {
5856                         Mutex::Autolock l(obj->mDefLock);
5857                         obj->mDefCond.broadcast();
5858                         LOGH("broadcast mDefCond signal\n");
5859                     }
5860                 default:
5861                     obj->processEvt(QCAMERA_SM_EVT_EVT_NOTIFY, payload);
5862                     break;
5863             }
5864         }
5865     } else {
5866         LOGE("NULL user_data");
5867     }
5868 }
5869 
5870 /*===========================================================================
5871  * FUNCTION   : jpegEvtHandle
5872  *
5873  * DESCRIPTION: Function registerd to mm-jpeg-interface to handle jpeg events
5874  *
5875  * PARAMETERS :
5876  *   @status    : status of jpeg job
5877  *   @client_hdl: jpeg client handle
5878  *   @jobId     : jpeg job Id
5879  *   @p_ouput   : ptr to jpeg output result struct
5880  *   @userdata  : user data ptr
5881  *
5882  * RETURN     : none
5883  *==========================================================================*/
jpegEvtHandle(jpeg_job_status_t status,uint32_t,uint32_t jobId,mm_jpeg_output_t * p_output,void * userdata)5884 void QCamera2HardwareInterface::jpegEvtHandle(jpeg_job_status_t status,
5885                                               uint32_t /*client_hdl*/,
5886                                               uint32_t jobId,
5887                                               mm_jpeg_output_t *p_output,
5888                                               void *userdata)
5889 {
5890     QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)userdata;
5891     if (obj) {
5892         qcamera_jpeg_evt_payload_t *payload =
5893             (qcamera_jpeg_evt_payload_t *)malloc(sizeof(qcamera_jpeg_evt_payload_t));
5894         if (NULL != payload) {
5895             memset(payload, 0, sizeof(qcamera_jpeg_evt_payload_t));
5896             payload->status = status;
5897             payload->jobId = jobId;
5898             if (p_output != NULL) {
5899                 payload->out_data = *p_output;
5900             }
5901             obj->processEvt(QCAMERA_SM_EVT_JPEG_EVT_NOTIFY, payload);
5902         }
5903     } else {
5904         LOGE("NULL user_data");
5905     }
5906 }
5907 
5908 /*===========================================================================
5909  * FUNCTION   : thermalEvtHandle
5910  *
5911  * DESCRIPTION: routine to handle thermal event notification
5912  *
5913  * PARAMETERS :
5914  *   @level      : thermal level
5915  *   @userdata   : userdata passed in during registration
5916  *   @data       : opaque data from thermal client
5917  *
5918  * RETURN     : int32_t type of status
5919  *              NO_ERROR  -- success
5920  *              none-zero failure code
5921  *==========================================================================*/
thermalEvtHandle(qcamera_thermal_level_enum_t * level,void * userdata,void * data)5922 int QCamera2HardwareInterface::thermalEvtHandle(
5923         qcamera_thermal_level_enum_t *level, void *userdata, void *data)
5924 {
5925     if (!mCameraOpened) {
5926         LOGH("Camera is not opened, no need to handle thermal evt");
5927         return NO_ERROR;
5928     }
5929 
5930     // Make sure thermal events are logged
5931     LOGH("level = %d, userdata = %p, data = %p",
5932          *level, userdata, data);
5933     //We don't need to lockAPI, waitAPI here. QCAMERA_SM_EVT_THERMAL_NOTIFY
5934     // becomes an aync call. This also means we can only pass payload
5935     // by value, not by address.
5936     return processAPI(QCAMERA_SM_EVT_THERMAL_NOTIFY, (void *)level);
5937 }
5938 
5939 /*===========================================================================
5940  * FUNCTION   : sendEvtNotify
5941  *
5942  * DESCRIPTION: send event notify to notify thread
5943  *
5944  * PARAMETERS :
5945  *   @msg_type: msg type to be sent
5946  *   @ext1    : optional extension1
5947  *   @ext2    : optional extension2
5948  *
5949  * RETURN     : int32_t type of status
5950  *              NO_ERROR  -- success
5951  *              none-zero failure code
5952  *==========================================================================*/
sendEvtNotify(int32_t msg_type,int32_t ext1,int32_t ext2)5953 int32_t QCamera2HardwareInterface::sendEvtNotify(int32_t msg_type,
5954                                                  int32_t ext1,
5955                                                  int32_t ext2)
5956 {
5957     qcamera_callback_argm_t cbArg;
5958     memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
5959     cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK;
5960     cbArg.msg_type = msg_type;
5961     cbArg.ext1 = ext1;
5962     cbArg.ext2 = ext2;
5963     return m_cbNotifier.notifyCallback(cbArg);
5964 }
5965 
5966 /*===========================================================================
5967  * FUNCTION   : processAEInfo
5968  *
5969  * DESCRIPTION: process AE updates
5970  *
5971  * PARAMETERS :
5972  *   @ae_params: current AE parameters
5973  *
5974  * RETURN     : None
5975  *==========================================================================*/
processAEInfo(cam_3a_params_t & ae_params)5976 int32_t QCamera2HardwareInterface::processAEInfo(cam_3a_params_t &ae_params)
5977 {
5978     mParameters.updateAEInfo(ae_params);
5979     if (mParameters.isInstantAECEnabled()) {
5980         // Reset Instant AEC info only if instant aec enabled.
5981         bool bResetInstantAec = false;
5982         if (ae_params.settled) {
5983             // If AEC settled, reset instant AEC
5984             bResetInstantAec = true;
5985         } else if ((mParameters.isInstantCaptureEnabled()) &&
5986                 (mInstantAecFrameCount >= mParameters.getAecFrameBoundValue())) {
5987             // if AEC not settled, and instant capture enabled,
5988             // reset instant AEC only when frame count is
5989             // more or equal to AEC frame bound value.
5990             bResetInstantAec = true;
5991         } else if ((mParameters.isInstantAECEnabled()) &&
5992                 (mInstantAecFrameCount >= mParameters.getAecSkipDisplayFrameBound())) {
5993             // if AEC not settled, and only instant AEC enabled,
5994             // reset instant AEC only when frame count is
5995             // more or equal to AEC skip display frame bound value.
5996             bResetInstantAec = true;
5997         }
5998 
5999         if (bResetInstantAec) {
6000             LOGD("setting instant AEC to false");
6001             mParameters.setInstantAEC(false, true);
6002             mInstantAecFrameCount = 0;
6003         }
6004     }
6005     return NO_ERROR;
6006 }
6007 
6008 /*===========================================================================
6009  * FUNCTION   : processFocusPositionInfo
6010  *
6011  * DESCRIPTION: process AF updates
6012  *
6013  * PARAMETERS :
6014  *   @cur_pos_info: current lens position
6015  *
6016  * RETURN     : None
6017  *==========================================================================*/
processFocusPositionInfo(cam_focus_pos_info_t & cur_pos_info)6018 int32_t QCamera2HardwareInterface::processFocusPositionInfo(cam_focus_pos_info_t &cur_pos_info)
6019 {
6020     mParameters.updateCurrentFocusPosition(cur_pos_info);
6021     return NO_ERROR;
6022 }
6023 
6024 /*===========================================================================
6025  * FUNCTION   : processAutoFocusEvent
6026  *
6027  * DESCRIPTION: process auto focus event
6028  *
6029  * PARAMETERS :
6030  *   @focus_data: struct containing auto focus result info
6031  *
6032  * RETURN     : int32_t type of status
6033  *              NO_ERROR  -- success
6034  *              none-zero failure code
6035  *==========================================================================*/
processAutoFocusEvent(cam_auto_focus_data_t & focus_data)6036 int32_t QCamera2HardwareInterface::processAutoFocusEvent(cam_auto_focus_data_t &focus_data)
6037 {
6038     int32_t ret = NO_ERROR;
6039     LOGH("E");
6040 
6041     if (getRelatedCamSyncInfo()->mode == CAM_MODE_SECONDARY) {
6042         // Ignore focus updates
6043         LOGH("X Secondary Camera, no need to process!! ");
6044         return ret;
6045     }
6046     cam_focus_mode_type focusMode = mParameters.getFocusMode();
6047     LOGH("[AF_DBG]  focusMode=%d, focusState=%d",
6048              focusMode, focus_data.focus_state);
6049 
6050     switch (focusMode) {
6051     case CAM_FOCUS_MODE_AUTO:
6052     case CAM_FOCUS_MODE_MACRO:
6053         // ignore AF event if AF was already cancelled meanwhile
6054         if (!mActiveAF) {
6055             break;
6056         }
6057         // If the HAL focus mode is different from AF INFINITY focus mode, send event to app
6058         if ((focus_data.focus_mode == CAM_FOCUS_MODE_INFINITY) &&
6059                 (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) {
6060             ret = sendEvtNotify(CAMERA_MSG_FOCUS, true, 0);
6061             mActiveAF = false; // reset the mActiveAF in this special case
6062             break;
6063         }
6064 
6065         //while transitioning from CAF->Auto/Macro, we might receive CAF related
6066         //events (PASSIVE_*) due to timing. Ignore such events if any.
6067         if ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN) ||
6068                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
6069                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED)) {
6070             break;
6071         }
6072 
6073         //This is just an intermediate update to HAL indicating focus is in progress. No need
6074         //to send this event to app. Same applies to INACTIVE state as well.
6075         if ((focus_data.focus_state == CAM_AF_STATE_ACTIVE_SCAN) ||
6076                 (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) {
6077             break;
6078         }
6079         // update focus distance
6080         mParameters.updateFocusDistances(&focus_data.focus_dist);
6081 
6082         //flush any old snapshot frames in ZSL Q which are not focused.
6083         if (mParameters.isZSLMode() && focus_data.flush_info.needFlush ) {
6084             QCameraPicChannel *pZSLChannel =
6085                     (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
6086             if (NULL != pZSLChannel) {
6087                 //flush the zsl-buffer
6088                 uint32_t flush_frame_idx = focus_data.flush_info.focused_frame_idx;
6089                 LOGD("flush the zsl-buffer before frame = %u.", flush_frame_idx);
6090                 pZSLChannel->flushSuperbuffer(flush_frame_idx);
6091             }
6092         }
6093 
6094         //send event to app finally
6095         LOGI("Send AF DOne event to app");
6096         ret = sendEvtNotify(CAMERA_MSG_FOCUS,
6097                             (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED), 0);
6098         break;
6099     case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
6100     case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
6101 
6102         // If the HAL focus mode is different from AF INFINITY focus mode, send event to app
6103         if ((focus_data.focus_mode == CAM_FOCUS_MODE_INFINITY) &&
6104                 (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) {
6105             ret = sendEvtNotify(CAMERA_MSG_FOCUS, false, 0);
6106             mActiveAF = false; // reset the mActiveAF in this special case
6107             break;
6108         }
6109 
6110         //If AutoFocus() is triggered while in CAF mode, ignore all CAF events (PASSIVE_*) and
6111         //process/wait for only ACTIVE_* events.
6112         if (((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
6113                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED) ||
6114                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN)) && mActiveAF) {
6115             break;
6116         }
6117 
6118         //These are the AF states for which we need to send notification to app in CAF mode.
6119         //This includes both regular CAF (PASSIVE) events as well as ACTIVE events ( in case
6120         //AF is triggered while in CAF mode)
6121         if ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
6122                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED) ||
6123                 (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED) ||
6124                 (focus_data.focus_state == CAM_AF_STATE_NOT_FOCUSED_LOCKED)) {
6125 
6126             // update focus distance
6127             mParameters.updateFocusDistances(&focus_data.focus_dist);
6128 
6129             if (mParameters.isZSLMode() && focus_data.flush_info.needFlush ) {
6130                 QCameraPicChannel *pZSLChannel =
6131                         (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
6132                 if (NULL != pZSLChannel) {
6133                     //flush the zsl-buffer
6134                     uint32_t flush_frame_idx = focus_data.flush_info.focused_frame_idx;
6135                     LOGD("flush the zsl-buffer before frame = %u.", flush_frame_idx);
6136                     pZSLChannel->flushSuperbuffer(flush_frame_idx);
6137                 }
6138             }
6139 
6140             if (mActiveAF) {
6141                 LOGI("Send AF Done event to app");
6142             }
6143             ret = sendEvtNotify(CAMERA_MSG_FOCUS,
6144                     ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
6145                     (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED)), 0);
6146         }
6147         ret = sendEvtNotify(CAMERA_MSG_FOCUS_MOVE,
6148                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN), 0);
6149         break;
6150     case CAM_FOCUS_MODE_INFINITY:
6151     case CAM_FOCUS_MODE_FIXED:
6152     case CAM_FOCUS_MODE_EDOF:
6153     default:
6154         LOGH("no ops for autofocus event in focusmode %d", focusMode);
6155         break;
6156     }
6157 
6158     //Reset mActiveAF once we receive focus done event
6159     if ((focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED) ||
6160             (focus_data.focus_state == CAM_AF_STATE_NOT_FOCUSED_LOCKED)) {
6161         mActiveAF = false;
6162     }
6163 
6164     LOGH("X");
6165     return ret;
6166 }
6167 
6168 /*===========================================================================
6169  * FUNCTION   : processZoomEvent
6170  *
6171  * DESCRIPTION: process zoom event
6172  *
6173  * PARAMETERS :
6174  *   @crop_info : crop info as a result of zoom operation
6175  *
6176  * RETURN     : int32_t type of status
6177  *              NO_ERROR  -- success
6178  *              none-zero failure code
6179  *==========================================================================*/
processZoomEvent(cam_crop_data_t & crop_info)6180 int32_t QCamera2HardwareInterface::processZoomEvent(cam_crop_data_t &crop_info)
6181 {
6182     int32_t ret = NO_ERROR;
6183 
6184     for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
6185         if (m_channels[i] != NULL) {
6186             ret = m_channels[i]->processZoomDone(mPreviewWindow, crop_info);
6187         }
6188     }
6189     return ret;
6190 }
6191 
6192 /*===========================================================================
6193  * FUNCTION   : processZSLCaptureDone
6194  *
6195  * DESCRIPTION: process ZSL capture done events
6196  *
6197  * PARAMETERS : None
6198  *
6199  * RETURN     : int32_t type of status
6200  *              NO_ERROR  -- success
6201  *              none-zero failure code
6202  *==========================================================================*/
processZSLCaptureDone()6203 int32_t QCamera2HardwareInterface::processZSLCaptureDone()
6204 {
6205     int rc = NO_ERROR;
6206 
6207     if (++mInputCount >= mParameters.getBurstCountForAdvancedCapture()) {
6208         rc = unconfigureAdvancedCapture();
6209     }
6210 
6211     return rc;
6212 }
6213 
6214 /*===========================================================================
6215  * FUNCTION   : processRetroAECUnlock
6216  *
6217  * DESCRIPTION: process retro burst AEC unlock events
6218  *
6219  * PARAMETERS : None
6220  *
6221  * RETURN     : int32_t type of status
6222  *              NO_ERROR  -- success
6223  *              none-zero failure code
6224  *==========================================================================*/
processRetroAECUnlock()6225 int32_t QCamera2HardwareInterface::processRetroAECUnlock()
6226 {
6227     int rc = NO_ERROR;
6228 
6229     LOGH("LED assisted AF Release AEC Lock");
6230     rc = mParameters.setAecLock("false");
6231     if (NO_ERROR != rc) {
6232         LOGE("Error setting AEC lock");
6233         return rc;
6234     }
6235 
6236     rc = mParameters.commitParameters();
6237     if (NO_ERROR != rc) {
6238         LOGE("Error during camera parameter commit");
6239     } else {
6240         m_bLedAfAecLock = FALSE;
6241     }
6242 
6243     return rc;
6244 }
6245 
6246 /*===========================================================================
6247  * FUNCTION   : processHDRData
6248  *
6249  * DESCRIPTION: process HDR scene events
6250  *
6251  * PARAMETERS :
6252  *   @hdr_scene : HDR scene event data
6253  *
6254  * RETURN     : int32_t type of status
6255  *              NO_ERROR  -- success
6256  *              none-zero failure code
6257  *==========================================================================*/
processHDRData(__unused cam_asd_hdr_scene_data_t hdr_scene)6258 int32_t QCamera2HardwareInterface::processHDRData(
6259         __unused cam_asd_hdr_scene_data_t hdr_scene)
6260 {
6261     int rc = NO_ERROR;
6262 
6263 #ifndef VANILLA_HAL
6264     if (hdr_scene.is_hdr_scene &&
6265       (hdr_scene.hdr_confidence > HDR_CONFIDENCE_THRESHOLD) &&
6266       mParameters.isAutoHDREnabled()) {
6267         m_HDRSceneEnabled = true;
6268     } else {
6269         m_HDRSceneEnabled = false;
6270     }
6271     mParameters.setHDRSceneEnable(m_HDRSceneEnabled);
6272 
6273     if ( msgTypeEnabled(CAMERA_MSG_META_DATA) ) {
6274 
6275         size_t data_len = sizeof(int);
6276         size_t buffer_len = 1 *sizeof(int)       //meta type
6277                           + 1 *sizeof(int)       //data len
6278                           + 1 *sizeof(int);      //data
6279         camera_memory_t *hdrBuffer = mGetMemory(-1,
6280                                                  buffer_len,
6281                                                  1,
6282                                                  mCallbackCookie);
6283         if ( NULL == hdrBuffer ) {
6284             LOGE("Not enough memory for auto HDR data");
6285             return NO_MEMORY;
6286         }
6287 
6288         int *pHDRData = (int *)hdrBuffer->data;
6289         if (pHDRData == NULL) {
6290             LOGE("memory data ptr is NULL");
6291             return UNKNOWN_ERROR;
6292         }
6293 
6294         pHDRData[0] = CAMERA_META_DATA_HDR;
6295         pHDRData[1] = (int)data_len;
6296         pHDRData[2] = m_HDRSceneEnabled;
6297 
6298         qcamera_callback_argm_t cbArg;
6299         memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
6300         cbArg.cb_type = QCAMERA_DATA_CALLBACK;
6301         cbArg.msg_type = CAMERA_MSG_META_DATA;
6302         cbArg.data = hdrBuffer;
6303         cbArg.user_data = hdrBuffer;
6304         cbArg.cookie = this;
6305         cbArg.release_cb = releaseCameraMemory;
6306         rc = m_cbNotifier.notifyCallback(cbArg);
6307         if (rc != NO_ERROR) {
6308             LOGE("fail sending auto HDR notification");
6309             hdrBuffer->release(hdrBuffer);
6310         }
6311     }
6312 
6313     LOGH("hdr_scene_data: processHDRData: %d %f",
6314           hdr_scene.is_hdr_scene,
6315           hdr_scene.hdr_confidence);
6316 
6317 #endif
6318   return rc;
6319 }
6320 
6321 /*===========================================================================
6322  * FUNCTION   : transAwbMetaToParams
6323  *
6324  * DESCRIPTION: translate awb params from metadata callback to QCameraParametersIntf
6325  *
6326  * PARAMETERS :
6327  *   @awb_params : awb params from metadata callback
6328  *
6329  * RETURN     : int32_t type of status
6330  *              NO_ERROR  -- success
6331  *              none-zero failure code
6332  *==========================================================================*/
transAwbMetaToParams(cam_awb_params_t & awb_params)6333 int32_t QCamera2HardwareInterface::transAwbMetaToParams(cam_awb_params_t &awb_params)
6334 {
6335     mParameters.updateAWBParams(awb_params);
6336     return NO_ERROR;
6337 }
6338 
6339 /*===========================================================================
6340  * FUNCTION   : processPrepSnapshotDone
6341  *
6342  * DESCRIPTION: process prep snapshot done event
6343  *
6344  * PARAMETERS :
6345  *   @prep_snapshot_state  : state of prepare snapshot done. In other words,
6346  *                           i.e. whether need future frames for capture.
6347  *
6348  * RETURN     : int32_t type of status
6349  *              NO_ERROR  -- success
6350  *              none-zero failure code
6351  *==========================================================================*/
processPrepSnapshotDoneEvent(cam_prep_snapshot_state_t prep_snapshot_state)6352 int32_t QCamera2HardwareInterface::processPrepSnapshotDoneEvent(
6353                         cam_prep_snapshot_state_t prep_snapshot_state)
6354 {
6355     int32_t ret = NO_ERROR;
6356     LOGI("[KPI Perf]: Received PREPARE SANSPHOT Done event state = %d",
6357             prep_snapshot_state);
6358     if (m_channels[QCAMERA_CH_TYPE_ZSL] &&
6359         prep_snapshot_state == NEED_FUTURE_FRAME) {
6360         LOGH("already handled in mm-camera-intf, no ops here");
6361         if (isRetroPicture()) {
6362             mParameters.setAecLock("true");
6363             mParameters.commitParameters();
6364             m_bLedAfAecLock = TRUE;
6365         }
6366     }
6367     return ret;
6368 }
6369 
6370 /*===========================================================================
6371  * FUNCTION   : processASDUpdate
6372  *
6373  * DESCRIPTION: process ASD update event
6374  *
6375  * PARAMETERS :
6376  *   @scene: selected scene mode
6377  *
6378  * RETURN     : int32_t type of status
6379  *              NO_ERROR  -- success
6380  *              none-zero failure code
6381  *==========================================================================*/
processASDUpdate(__unused cam_asd_decision_t asd_decision)6382 int32_t QCamera2HardwareInterface::processASDUpdate(
6383         __unused cam_asd_decision_t asd_decision)
6384 {
6385     size_t data_len = sizeof(cam_auto_scene_t);
6386     size_t buffer_len = 1 *sizeof(int)       //meta type
6387                       + 1 *sizeof(int)       //data len
6388                       + data_len;            //data
6389     camera_memory_t *asdBuffer = mGetMemory(-1,
6390                                              buffer_len,
6391                                              1,
6392                                              mCallbackCookie);
6393     if ( NULL == asdBuffer ) {
6394         LOGE("Not enough memory for histogram data");
6395         return NO_MEMORY;
6396     }
6397 
6398     int *pASDData = (int *)asdBuffer->data;
6399     if (pASDData == NULL) {
6400         LOGE("memory data ptr is NULL");
6401         return UNKNOWN_ERROR;
6402     }
6403 
6404 #ifndef VANILLA_HAL
6405     pASDData[0] = CAMERA_META_DATA_ASD;
6406     pASDData[1] = (int)data_len;
6407     pASDData[2] = asd_decision.detected_scene;
6408 
6409     qcamera_callback_argm_t cbArg;
6410     memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
6411     cbArg.cb_type = QCAMERA_DATA_CALLBACK;
6412     cbArg.msg_type = CAMERA_MSG_META_DATA;
6413     cbArg.data = asdBuffer;
6414     cbArg.user_data = asdBuffer;
6415     cbArg.cookie = this;
6416     cbArg.release_cb = releaseCameraMemory;
6417     int32_t rc = m_cbNotifier.notifyCallback(cbArg);
6418     if (rc != NO_ERROR) {
6419         LOGE("fail sending notification");
6420         asdBuffer->release(asdBuffer);
6421     }
6422 #endif
6423     return NO_ERROR;
6424 
6425 }
6426 
6427 /*===========================================================================
6428  * FUNCTION   : processJpegNotify
6429  *
6430  * DESCRIPTION: process jpeg event
6431  *
6432  * PARAMETERS :
6433  *   @jpeg_evt: ptr to jpeg event payload
6434  *
6435  * RETURN     : int32_t type of status
6436  *              NO_ERROR  -- success
6437  *              none-zero failure code
6438  *==========================================================================*/
processJpegNotify(qcamera_jpeg_evt_payload_t * jpeg_evt)6439 int32_t QCamera2HardwareInterface::processJpegNotify(qcamera_jpeg_evt_payload_t *jpeg_evt)
6440 {
6441     return m_postprocessor.processJpegEvt(jpeg_evt);
6442 }
6443 
6444 /*===========================================================================
6445  * FUNCTION   : lockAPI
6446  *
6447  * DESCRIPTION: lock to process API
6448  *
6449  * PARAMETERS : none
6450  *
6451  * RETURN     : none
6452  *==========================================================================*/
lockAPI()6453 void QCamera2HardwareInterface::lockAPI()
6454 {
6455     pthread_mutex_lock(&m_lock);
6456 }
6457 
6458 /*===========================================================================
6459  * FUNCTION   : waitAPIResult
6460  *
6461  * DESCRIPTION: wait for API result coming back. This is a blocking call, it will
6462  *              return only cerntain API event type arrives
6463  *
6464  * PARAMETERS :
6465  *   @api_evt : API event type
6466  *
6467  * RETURN     : none
6468  *==========================================================================*/
waitAPIResult(qcamera_sm_evt_enum_t api_evt,qcamera_api_result_t * apiResult)6469 void QCamera2HardwareInterface::waitAPIResult(qcamera_sm_evt_enum_t api_evt,
6470         qcamera_api_result_t *apiResult)
6471 {
6472     LOGD("wait for API result of evt (%d)", api_evt);
6473     int resultReceived = 0;
6474     while  (!resultReceived) {
6475         pthread_cond_wait(&m_cond, &m_lock);
6476         if (m_apiResultList != NULL) {
6477             api_result_list *apiResultList = m_apiResultList;
6478             api_result_list *apiResultListPrevious = m_apiResultList;
6479             while (apiResultList != NULL) {
6480                 if (apiResultList->result.request_api == api_evt) {
6481                     resultReceived = 1;
6482                     *apiResult = apiResultList->result;
6483                     apiResultListPrevious->next = apiResultList->next;
6484                     if (apiResultList == m_apiResultList) {
6485                         m_apiResultList = apiResultList->next;
6486                     }
6487                     free(apiResultList);
6488                     break;
6489                 }
6490                 else {
6491                     apiResultListPrevious = apiResultList;
6492                     apiResultList = apiResultList->next;
6493                 }
6494             }
6495         }
6496     }
6497     LOGD("return (%d) from API result wait for evt (%d)",
6498            apiResult->status, api_evt);
6499 }
6500 
6501 
6502 /*===========================================================================
6503  * FUNCTION   : unlockAPI
6504  *
6505  * DESCRIPTION: API processing is done, unlock
6506  *
6507  * PARAMETERS : none
6508  *
6509  * RETURN     : none
6510  *==========================================================================*/
unlockAPI()6511 void QCamera2HardwareInterface::unlockAPI()
6512 {
6513     pthread_mutex_unlock(&m_lock);
6514 }
6515 
6516 /*===========================================================================
6517  * FUNCTION   : signalAPIResult
6518  *
6519  * DESCRIPTION: signal condition viarable that cerntain API event type arrives
6520  *
6521  * PARAMETERS :
6522  *   @result  : API result
6523  *
6524  * RETURN     : none
6525  *==========================================================================*/
signalAPIResult(qcamera_api_result_t * result)6526 void QCamera2HardwareInterface::signalAPIResult(qcamera_api_result_t *result)
6527 {
6528 
6529     pthread_mutex_lock(&m_lock);
6530     api_result_list *apiResult = (api_result_list *)malloc(sizeof(api_result_list));
6531     if (apiResult == NULL) {
6532         LOGE("ERROR: malloc for api result failed, Result will not be sent");
6533         goto malloc_failed;
6534     }
6535     apiResult->result = *result;
6536     apiResult->next = NULL;
6537     if (m_apiResultList == NULL) m_apiResultList = apiResult;
6538     else {
6539         api_result_list *apiResultList = m_apiResultList;
6540         while(apiResultList->next != NULL) apiResultList = apiResultList->next;
6541         apiResultList->next = apiResult;
6542     }
6543 malloc_failed:
6544     pthread_cond_broadcast(&m_cond);
6545     pthread_mutex_unlock(&m_lock);
6546 }
6547 
6548 /*===========================================================================
6549  * FUNCTION   : signalEvtResult
6550  *
6551  * DESCRIPTION: signal condition variable that certain event was processed
6552  *
6553  * PARAMETERS :
6554  *   @result  : Event result
6555  *
6556  * RETURN     : none
6557  *==========================================================================*/
signalEvtResult(qcamera_api_result_t * result)6558 void QCamera2HardwareInterface::signalEvtResult(qcamera_api_result_t *result)
6559 {
6560     pthread_mutex_lock(&m_evtLock);
6561     m_evtResult = *result;
6562     pthread_cond_signal(&m_evtCond);
6563     pthread_mutex_unlock(&m_evtLock);
6564 }
6565 
prepareRawStream(QCameraChannel * curChannel)6566 int32_t QCamera2HardwareInterface::prepareRawStream(QCameraChannel *curChannel)
6567 {
6568     int32_t rc = NO_ERROR;
6569     cam_dimension_t str_dim,max_dim;
6570     QCameraChannel *pChannel;
6571 
6572     max_dim.width = 0;
6573     max_dim.height = 0;
6574 
6575     for (int j = 0; j < QCAMERA_CH_TYPE_MAX; j++) {
6576         if (m_channels[j] != NULL) {
6577             pChannel = m_channels[j];
6578             for (uint8_t i = 0; i < pChannel->getNumOfStreams(); i++) {
6579                 QCameraStream *pStream = pChannel->getStreamByIndex(i);
6580                 if (pStream != NULL) {
6581                     if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA))
6582                             || (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW))) {
6583                         continue;
6584                     }
6585                     pStream->getFrameDimension(str_dim);
6586                     if (str_dim.width > max_dim.width) {
6587                         max_dim.width = str_dim.width;
6588                     }
6589                     if (str_dim.height > max_dim.height) {
6590                         max_dim.height = str_dim.height;
6591                     }
6592                 }
6593             }
6594         }
6595     }
6596 
6597     for (uint8_t i = 0; i < curChannel->getNumOfStreams(); i++) {
6598         QCameraStream *pStream = curChannel->getStreamByIndex(i);
6599         if (pStream != NULL) {
6600             if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA))
6601                     || (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW))) {
6602                 continue;
6603             }
6604             pStream->getFrameDimension(str_dim);
6605             if (str_dim.width > max_dim.width) {
6606                 max_dim.width = str_dim.width;
6607             }
6608             if (str_dim.height > max_dim.height) {
6609                 max_dim.height = str_dim.height;
6610             }
6611         }
6612     }
6613     rc = mParameters.updateRAW(max_dim);
6614     return rc;
6615 }
6616 /*===========================================================================
6617  * FUNCTION   : addStreamToChannel
6618  *
6619  * DESCRIPTION: add a stream into a channel
6620  *
6621  * PARAMETERS :
6622  *   @pChannel   : ptr to channel obj
6623  *   @streamType : type of stream to be added
6624  *   @streamCB   : callback of stream
6625  *   @userData   : user data ptr to callback
6626  *
6627  * RETURN     : int32_t type of status
6628  *              NO_ERROR  -- success
6629  *              none-zero failure code
6630  *==========================================================================*/
addStreamToChannel(QCameraChannel * pChannel,cam_stream_type_t streamType,stream_cb_routine streamCB,void * userData)6631 int32_t QCamera2HardwareInterface::addStreamToChannel(QCameraChannel *pChannel,
6632                                                       cam_stream_type_t streamType,
6633                                                       stream_cb_routine streamCB,
6634                                                       void *userData)
6635 {
6636     int32_t rc = NO_ERROR;
6637 
6638     if (streamType == CAM_STREAM_TYPE_RAW) {
6639         prepareRawStream(pChannel);
6640     }
6641     QCameraHeapMemory *pStreamInfo = allocateStreamInfoBuf(streamType);
6642     if (pStreamInfo == NULL) {
6643         LOGE("no mem for stream info buf");
6644         return NO_MEMORY;
6645     }
6646     uint8_t minStreamBufNum = getBufNumRequired(streamType);
6647     bool bDynAllocBuf = false;
6648     if (isZSLMode() && streamType == CAM_STREAM_TYPE_SNAPSHOT) {
6649         bDynAllocBuf = true;
6650     }
6651 
6652     cam_padding_info_t padding_info;
6653     if (streamType == CAM_STREAM_TYPE_ANALYSIS) {
6654         padding_info =
6655                 gCamCapability[mCameraId]->analysis_padding_info;
6656     } else {
6657         padding_info =
6658                 gCamCapability[mCameraId]->padding_info;
6659         if (streamType == CAM_STREAM_TYPE_PREVIEW) {
6660             padding_info.width_padding = mSurfaceStridePadding;
6661             padding_info.height_padding = CAM_PAD_TO_2;
6662         }
6663         if((!needReprocess())
6664                 || (streamType != CAM_STREAM_TYPE_SNAPSHOT)
6665                 || (!mParameters.isLLNoiseEnabled())) {
6666             padding_info.offset_info.offset_x = 0;
6667             padding_info.offset_info.offset_y = 0;
6668         }
6669     }
6670 
6671     bool deferAllocation = needDeferred(streamType);
6672     LOGD("deferAllocation = %d bDynAllocBuf = %d, stream type = %d",
6673             deferAllocation, bDynAllocBuf, streamType);
6674     rc = pChannel->addStream(*this,
6675             pStreamInfo,
6676             NULL,
6677             minStreamBufNum,
6678             &padding_info,
6679             streamCB, userData,
6680             bDynAllocBuf,
6681             deferAllocation);
6682 
6683     if (rc != NO_ERROR) {
6684         LOGE("add stream type (%d) failed, ret = %d",
6685                streamType, rc);
6686         return rc;
6687     }
6688 
6689     return rc;
6690 }
6691 
6692 /*===========================================================================
6693  * FUNCTION   : addPreviewChannel
6694  *
6695  * DESCRIPTION: add a preview channel that contains a preview stream
6696  *
6697  * PARAMETERS : none
6698  *
6699  * RETURN     : int32_t type of status
6700  *              NO_ERROR  -- success
6701  *              none-zero failure code
6702  *==========================================================================*/
addPreviewChannel()6703 int32_t QCamera2HardwareInterface::addPreviewChannel()
6704 {
6705     int32_t rc = NO_ERROR;
6706     QCameraChannel *pChannel = NULL;
6707     char value[PROPERTY_VALUE_MAX];
6708     bool raw_yuv = false;
6709 
6710 
6711     if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
6712         // if we had preview channel before, delete it first
6713         delete m_channels[QCAMERA_CH_TYPE_PREVIEW];
6714         m_channels[QCAMERA_CH_TYPE_PREVIEW] = NULL;
6715     }
6716 
6717     pChannel = new QCameraChannel(mCameraHandle->camera_handle,
6718                                   mCameraHandle->ops);
6719     if (NULL == pChannel) {
6720         LOGE("no mem for preview channel");
6721         return NO_MEMORY;
6722     }
6723 
6724     // preview only channel, don't need bundle attr and cb
6725     rc = pChannel->init(NULL, NULL, NULL);
6726     if (rc != NO_ERROR) {
6727         LOGE("init preview channel failed, ret = %d", rc);
6728         return rc;
6729     }
6730 
6731     // meta data stream always coexists with preview if applicable
6732     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
6733                             metadata_stream_cb_routine, this);
6734     if (rc != NO_ERROR) {
6735         LOGE("add metadata stream failed, ret = %d", rc);
6736         return rc;
6737     }
6738 
6739     if (isRdiMode()) {
6740         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
6741                                 rdi_mode_stream_cb_routine, this);
6742     } else {
6743         if (isNoDisplayMode()) {
6744             rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
6745                                     nodisplay_preview_stream_cb_routine, this);
6746         } else {
6747             rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
6748                                     preview_stream_cb_routine, this);
6749             pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
6750                     synchronous_stream_cb_routine);
6751         }
6752     }
6753 
6754     if (((mParameters.fdModeInVideo())
6755             || (mParameters.getDcrf() == true)
6756             || (mParameters.getRecordingHintValue() != true))
6757             && (!mParameters.isSecureMode())) {
6758         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
6759                 NULL, this);
6760         if (rc != NO_ERROR) {
6761             LOGE("add Analysis stream failed, ret = %d", rc);
6762             return rc;
6763         }
6764     }
6765 
6766     property_get("persist.camera.raw_yuv", value, "0");
6767     raw_yuv = atoi(value) > 0 ? true : false;
6768     if ( raw_yuv ) {
6769         rc = addStreamToChannel(pChannel,CAM_STREAM_TYPE_RAW,
6770                 preview_raw_stream_cb_routine,this);
6771         if ( rc != NO_ERROR ) {
6772             LOGE("add raw stream failed, ret = %d", __FUNCTION__, rc);
6773             delete pChannel;
6774             return rc;
6775         }
6776     }
6777 
6778     if (rc != NO_ERROR) {
6779         LOGE("add preview stream failed, ret = %d", rc);
6780         delete pChannel;
6781         return rc;
6782     }
6783 
6784     m_channels[QCAMERA_CH_TYPE_PREVIEW] = pChannel;
6785     return rc;
6786 }
6787 
6788 /*===========================================================================
6789  * FUNCTION   : addVideoChannel
6790  *
6791  * DESCRIPTION: add a video channel that contains a video stream
6792  *
6793  * PARAMETERS : none
6794  *
6795  * RETURN     : int32_t type of status
6796  *              NO_ERROR  -- success
6797  *              none-zero failure code
6798  *==========================================================================*/
addVideoChannel()6799 int32_t QCamera2HardwareInterface::addVideoChannel()
6800 {
6801     int32_t rc = NO_ERROR;
6802     QCameraVideoChannel *pChannel = NULL;
6803 
6804     if (m_channels[QCAMERA_CH_TYPE_VIDEO] != NULL) {
6805         // if we had video channel before, delete it first
6806         delete m_channels[QCAMERA_CH_TYPE_VIDEO];
6807         m_channels[QCAMERA_CH_TYPE_VIDEO] = NULL;
6808     }
6809 
6810     pChannel = new QCameraVideoChannel(mCameraHandle->camera_handle,
6811                                        mCameraHandle->ops);
6812     if (NULL == pChannel) {
6813         LOGE("no mem for video channel");
6814         return NO_MEMORY;
6815     }
6816 
6817     if (isLowPowerMode()) {
6818         mm_camera_channel_attr_t attr;
6819         memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
6820         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
6821         attr.look_back = 0; //wait for future frame for liveshot
6822         attr.post_frame_skip = mParameters.getZSLBurstInterval();
6823         attr.water_mark = 1; //hold min buffers possible in Q
6824         attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
6825         rc = pChannel->init(&attr, snapshot_channel_cb_routine, this);
6826     } else {
6827         // preview only channel, don't need bundle attr and cb
6828         rc = pChannel->init(NULL, NULL, NULL);
6829     }
6830 
6831     if (rc != 0) {
6832         LOGE("init video channel failed, ret = %d", rc);
6833         delete pChannel;
6834         return rc;
6835     }
6836 
6837     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_VIDEO,
6838                             video_stream_cb_routine, this);
6839     if (rc != NO_ERROR) {
6840         LOGE("add video stream failed, ret = %d", rc);
6841         delete pChannel;
6842         return rc;
6843     }
6844 
6845     m_channels[QCAMERA_CH_TYPE_VIDEO] = pChannel;
6846     return rc;
6847 }
6848 
6849 /*===========================================================================
6850  * FUNCTION   : addSnapshotChannel
6851  *
6852  * DESCRIPTION: add a snapshot channel that contains a snapshot stream
6853  *
6854  * PARAMETERS : none
6855  *
6856  * RETURN     : int32_t type of status
6857  *              NO_ERROR  -- success
6858  *              none-zero failure code
6859  * NOTE       : Add this channel for live snapshot usecase. Regular capture will
6860  *              use addCaptureChannel.
6861  *==========================================================================*/
addSnapshotChannel()6862 int32_t QCamera2HardwareInterface::addSnapshotChannel()
6863 {
6864     int32_t rc = NO_ERROR;
6865     QCameraChannel *pChannel = NULL;
6866 
6867     if (m_channels[QCAMERA_CH_TYPE_SNAPSHOT] != NULL) {
6868         // if we had ZSL channel before, delete it first
6869         delete m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
6870         m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = NULL;
6871     }
6872 
6873     pChannel = new QCameraChannel(mCameraHandle->camera_handle,
6874                                   mCameraHandle->ops);
6875     if (NULL == pChannel) {
6876         LOGE("no mem for snapshot channel");
6877         return NO_MEMORY;
6878     }
6879 
6880     mm_camera_channel_attr_t attr;
6881     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
6882     attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
6883     attr.look_back = 0; //wait for future frame for liveshot
6884     attr.post_frame_skip = mParameters.getZSLBurstInterval();
6885     attr.water_mark = 1; //hold min buffers possible in Q
6886     attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
6887     attr.priority = MM_CAMERA_SUPER_BUF_PRIORITY_LOW;
6888     rc = pChannel->init(&attr, snapshot_channel_cb_routine, this);
6889     if (rc != NO_ERROR) {
6890         LOGE("init snapshot channel failed, ret = %d", rc);
6891         delete pChannel;
6892         return rc;
6893     }
6894 
6895     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
6896             NULL, NULL);
6897     if (rc != NO_ERROR) {
6898         LOGE("add snapshot stream failed, ret = %d", rc);
6899         delete pChannel;
6900         return rc;
6901     }
6902 
6903     m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = pChannel;
6904     return rc;
6905 }
6906 
6907 /*===========================================================================
6908  * FUNCTION   : addRawChannel
6909  *
6910  * DESCRIPTION: add a raw channel that contains a raw image stream
6911  *
6912  * PARAMETERS : none
6913  *
6914  * RETURN     : int32_t type of status
6915  *              NO_ERROR  -- success
6916  *              none-zero failure code
6917  *==========================================================================*/
addRawChannel()6918 int32_t QCamera2HardwareInterface::addRawChannel()
6919 {
6920     int32_t rc = NO_ERROR;
6921     QCameraChannel *pChannel = NULL;
6922 
6923     if (m_channels[QCAMERA_CH_TYPE_RAW] != NULL) {
6924         // if we had raw channel before, delete it first
6925         delete m_channels[QCAMERA_CH_TYPE_RAW];
6926         m_channels[QCAMERA_CH_TYPE_RAW] = NULL;
6927     }
6928 
6929     pChannel = new QCameraChannel(mCameraHandle->camera_handle,
6930                                   mCameraHandle->ops);
6931     if (NULL == pChannel) {
6932         LOGE("no mem for raw channel");
6933         return NO_MEMORY;
6934     }
6935 
6936     if (mParameters.getofflineRAW()) {
6937         mm_camera_channel_attr_t attr;
6938         memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
6939         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
6940         attr.look_back = mParameters.getZSLBackLookCount();
6941         attr.post_frame_skip = mParameters.getZSLBurstInterval();
6942         attr.water_mark = 1;
6943         attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
6944         rc = pChannel->init(&attr, raw_channel_cb_routine, this);
6945         if (rc != NO_ERROR) {
6946             LOGE("init RAW channel failed, ret = %d", rc);
6947             delete pChannel;
6948             return rc;
6949         }
6950     } else {
6951         rc = pChannel->init(NULL, NULL, NULL);
6952         if (rc != NO_ERROR) {
6953             LOGE("init raw channel failed, ret = %d", rc);
6954             delete pChannel;
6955             return rc;
6956         }
6957     }
6958 
6959     if (!mParameters.isZSLMode()) {
6960         // meta data stream always coexists with snapshot in regular RAW capture case
6961         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
6962                 metadata_stream_cb_routine, this);
6963         if (rc != NO_ERROR) {
6964             LOGE("add metadata stream failed, ret = %d", rc);
6965             delete pChannel;
6966             return rc;
6967         }
6968     }
6969 
6970     if (mParameters.getofflineRAW()) {
6971         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
6972                 NULL, this);
6973     } else {
6974         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
6975                 raw_stream_cb_routine, this);
6976     }
6977     if (rc != NO_ERROR) {
6978         LOGE("add snapshot stream failed, ret = %d", rc);
6979         delete pChannel;
6980         return rc;
6981     }
6982     m_channels[QCAMERA_CH_TYPE_RAW] = pChannel;
6983     return rc;
6984 }
6985 
6986 /*===========================================================================
6987  * FUNCTION   : addZSLChannel
6988  *
6989  * DESCRIPTION: add a ZSL channel that contains a preview stream and
6990  *              a snapshot stream
6991  *
6992  * PARAMETERS : none
6993  *
6994  * RETURN     : int32_t type of status
6995  *              NO_ERROR  -- success
6996  *              none-zero failure code
6997  *==========================================================================*/
addZSLChannel()6998 int32_t QCamera2HardwareInterface::addZSLChannel()
6999 {
7000     int32_t rc = NO_ERROR;
7001     QCameraPicChannel *pChannel = NULL;
7002     char value[PROPERTY_VALUE_MAX];
7003     bool raw_yuv = false;
7004 
7005     if (m_channels[QCAMERA_CH_TYPE_ZSL] != NULL) {
7006         // if we had ZSL channel before, delete it first
7007         delete m_channels[QCAMERA_CH_TYPE_ZSL];
7008         m_channels[QCAMERA_CH_TYPE_ZSL] = NULL;
7009     }
7010 
7011     pChannel = new QCameraPicChannel(mCameraHandle->camera_handle,
7012                                      mCameraHandle->ops);
7013     if (NULL == pChannel) {
7014         LOGE("no mem for ZSL channel");
7015         return NO_MEMORY;
7016     }
7017 
7018     // ZSL channel, init with bundle attr and cb
7019     mm_camera_channel_attr_t attr;
7020     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
7021     if (mParameters.isSceneSelectionEnabled()) {
7022         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
7023     } else {
7024         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
7025     }
7026     attr.look_back = mParameters.getZSLBackLookCount();
7027     attr.post_frame_skip = mParameters.getZSLBurstInterval();
7028     if (mParameters.isOEMFeatEnabled()) {
7029         attr.post_frame_skip++;
7030     }
7031     attr.water_mark = mParameters.getZSLQueueDepth();
7032     attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
7033     attr.user_expected_frame_id =
7034         mParameters.isInstantCaptureEnabled() ? (uint8_t)mParameters.getAecFrameBoundValue() : 0;
7035 
7036     //Enabled matched queue
7037     if (getRelatedCamSyncInfo()->is_frame_sync_enabled) {
7038         LOGH("Enabling frame sync for dual camera, camera Id: %d",
7039                  mCameraId);
7040         attr.enable_frame_sync = 1;
7041     }
7042     rc = pChannel->init(&attr,
7043                         zsl_channel_cb,
7044                         this);
7045     if (rc != 0) {
7046         LOGE("init ZSL channel failed, ret = %d", rc);
7047         delete pChannel;
7048         return rc;
7049     }
7050 
7051     // meta data stream always coexists with preview if applicable
7052     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
7053                             metadata_stream_cb_routine, this);
7054     if (rc != NO_ERROR) {
7055         LOGE("add metadata stream failed, ret = %d", rc);
7056         delete pChannel;
7057         return rc;
7058     }
7059 
7060     if (isNoDisplayMode()) {
7061         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
7062                                 nodisplay_preview_stream_cb_routine, this);
7063     } else {
7064         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
7065                                 preview_stream_cb_routine, this);
7066         pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
7067                 synchronous_stream_cb_routine);
7068     }
7069     if (rc != NO_ERROR) {
7070         LOGE("add preview stream failed, ret = %d", rc);
7071         delete pChannel;
7072         return rc;
7073     }
7074 
7075     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
7076                             NULL, this);
7077     if (rc != NO_ERROR) {
7078         LOGE("add snapshot stream failed, ret = %d", rc);
7079         delete pChannel;
7080         return rc;
7081     }
7082 
7083     if (!mParameters.isSecureMode()) {
7084         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
7085                 NULL, this);
7086         if (rc != NO_ERROR) {
7087             LOGE("add Analysis stream failed, ret = %d", rc);
7088             delete pChannel;
7089             return rc;
7090         }
7091     }
7092 
7093     property_get("persist.camera.raw_yuv", value, "0");
7094     raw_yuv = atoi(value) > 0 ? true : false;
7095     if (raw_yuv) {
7096         rc = addStreamToChannel(pChannel,
7097                                 CAM_STREAM_TYPE_RAW,
7098                                 NULL,
7099                                 this);
7100         if (rc != NO_ERROR) {
7101             LOGE("add raw stream failed, ret = %d", rc);
7102             delete pChannel;
7103             return rc;
7104         }
7105     }
7106 
7107     m_channels[QCAMERA_CH_TYPE_ZSL] = pChannel;
7108     return rc;
7109 }
7110 
7111 /*===========================================================================
7112  * FUNCTION   : addCaptureChannel
7113  *
7114  * DESCRIPTION: add a capture channel that contains a snapshot stream
7115  *              and a postview stream
7116  *
7117  * PARAMETERS : none
7118  *
7119  * RETURN     : int32_t type of status
7120  *              NO_ERROR  -- success
7121  *              none-zero failure code
7122  * NOTE       : Add this channel for regular capture usecase.
7123  *              For Live snapshot usecase, use addSnapshotChannel.
7124  *==========================================================================*/
addCaptureChannel()7125 int32_t QCamera2HardwareInterface::addCaptureChannel()
7126 {
7127     int32_t rc = NO_ERROR;
7128     QCameraPicChannel *pChannel = NULL;
7129     char value[PROPERTY_VALUE_MAX];
7130     bool raw_yuv = false;
7131 
7132     if (m_channels[QCAMERA_CH_TYPE_CAPTURE] != NULL) {
7133         delete m_channels[QCAMERA_CH_TYPE_CAPTURE];
7134         m_channels[QCAMERA_CH_TYPE_CAPTURE] = NULL;
7135     }
7136 
7137     pChannel = new QCameraPicChannel(mCameraHandle->camera_handle,
7138                                   mCameraHandle->ops);
7139     if (NULL == pChannel) {
7140         LOGE("no mem for capture channel");
7141         return NO_MEMORY;
7142     }
7143 
7144     // Capture channel, only need snapshot and postview streams start together
7145     mm_camera_channel_attr_t attr;
7146     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
7147     if ( mLongshotEnabled ) {
7148         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
7149         attr.look_back = mParameters.getZSLBackLookCount();
7150         attr.water_mark = mParameters.getZSLQueueDepth();
7151     } else {
7152         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
7153     }
7154     attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
7155 
7156     rc = pChannel->init(&attr,
7157                         capture_channel_cb_routine,
7158                         this);
7159     if (rc != NO_ERROR) {
7160         LOGE("init capture channel failed, ret = %d", rc);
7161         return rc;
7162     }
7163 
7164     // meta data stream always coexists with snapshot in regular capture case
7165     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
7166                             metadata_stream_cb_routine, this);
7167     if (rc != NO_ERROR) {
7168         LOGE("add metadata stream failed, ret = %d", rc);
7169         return rc;
7170     }
7171 
7172     if (!mLongshotEnabled) {
7173         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_POSTVIEW,
7174                                 NULL, this);
7175 
7176         if (rc != NO_ERROR) {
7177             LOGE("add postview stream failed, ret = %d", rc);
7178             return rc;
7179         }
7180     } else {
7181         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
7182                                 preview_stream_cb_routine, this);
7183 
7184         if (rc != NO_ERROR) {
7185             LOGE("add preview stream failed, ret = %d", rc);
7186             return rc;
7187         }
7188         pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
7189                 synchronous_stream_cb_routine);
7190     }
7191 
7192     if (!mParameters.getofflineRAW()) {
7193         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
7194                 NULL, this);
7195         if (rc != NO_ERROR) {
7196             LOGE("add snapshot stream failed, ret = %d", rc);
7197             return rc;
7198         }
7199     }
7200 
7201     stream_cb_routine stream_cb = NULL;
7202     property_get("persist.camera.raw_yuv", value, "0");
7203     raw_yuv = atoi(value) > 0 ? true : false;
7204 
7205     if (raw_yuv) {
7206         stream_cb = snapshot_raw_stream_cb_routine;
7207     }
7208 
7209     if ((raw_yuv) || (mParameters.getofflineRAW())) {
7210         rc = addStreamToChannel(pChannel,
7211                 CAM_STREAM_TYPE_RAW, stream_cb, this);
7212         if (rc != NO_ERROR) {
7213             LOGE("add raw stream failed, ret = %d", rc);
7214             return rc;
7215         }
7216     }
7217 
7218     m_channels[QCAMERA_CH_TYPE_CAPTURE] = pChannel;
7219     return rc;
7220 }
7221 
7222 /*===========================================================================
7223  * FUNCTION   : addMetaDataChannel
7224  *
7225  * DESCRIPTION: add a meta data channel that contains a metadata stream
7226  *
7227  * PARAMETERS : none
7228  *
7229  * RETURN     : int32_t type of status
7230  *              NO_ERROR  -- success
7231  *              none-zero failure code
7232  *==========================================================================*/
addMetaDataChannel()7233 int32_t QCamera2HardwareInterface::addMetaDataChannel()
7234 {
7235     int32_t rc = NO_ERROR;
7236     QCameraChannel *pChannel = NULL;
7237 
7238     if (m_channels[QCAMERA_CH_TYPE_METADATA] != NULL) {
7239         delete m_channels[QCAMERA_CH_TYPE_METADATA];
7240         m_channels[QCAMERA_CH_TYPE_METADATA] = NULL;
7241     }
7242 
7243     pChannel = new QCameraChannel(mCameraHandle->camera_handle,
7244                                   mCameraHandle->ops);
7245     if (NULL == pChannel) {
7246         LOGE("no mem for metadata channel");
7247         return NO_MEMORY;
7248     }
7249 
7250     rc = pChannel->init(NULL,
7251                         NULL,
7252                         NULL);
7253     if (rc != NO_ERROR) {
7254         LOGE("init metadata channel failed, ret = %d", rc);
7255         delete pChannel;
7256         return rc;
7257     }
7258 
7259     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
7260                             metadata_stream_cb_routine, this);
7261     if (rc != NO_ERROR) {
7262         LOGE("add metadata stream failed, ret = %d", rc);
7263         delete pChannel;
7264         return rc;
7265     }
7266 
7267     m_channels[QCAMERA_CH_TYPE_METADATA] = pChannel;
7268     return rc;
7269 }
7270 
7271 /*===========================================================================
7272  * FUNCTION   : addCallbackChannel
7273  *
7274  * DESCRIPTION: add a callback channel that contains a callback stream
7275  *
7276  * PARAMETERS : none
7277  *
7278  * RETURN     : int32_t type of status
7279  *              NO_ERROR  -- success
7280  *              none-zero failure code
7281  *==========================================================================*/
addCallbackChannel()7282 int32_t QCamera2HardwareInterface::addCallbackChannel()
7283 {
7284     int32_t rc = NO_ERROR;
7285     QCameraChannel *pChannel = NULL;
7286 
7287     if (m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL) {
7288         delete m_channels[QCAMERA_CH_TYPE_CALLBACK];
7289         m_channels[QCAMERA_CH_TYPE_CALLBACK] = NULL;
7290     }
7291 
7292     pChannel = new QCameraChannel(mCameraHandle->camera_handle,
7293             mCameraHandle->ops);
7294     if (NULL == pChannel) {
7295         LOGE("no mem for callback channel");
7296         return NO_MEMORY;
7297     }
7298 
7299     rc = pChannel->init(NULL, NULL, this);
7300     if (rc != NO_ERROR) {
7301         LOGE("init callback channel failed, ret = %d",
7302                  rc);
7303         delete pChannel;
7304         return rc;
7305     }
7306 
7307     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_CALLBACK,
7308             callback_stream_cb_routine, this);
7309     if (rc != NO_ERROR) {
7310         LOGE("add callback stream failed, ret = %d", rc);
7311         delete pChannel;
7312         return rc;
7313     }
7314 
7315     m_channels[QCAMERA_CH_TYPE_CALLBACK] = pChannel;
7316     return rc;
7317 }
7318 
7319 
7320 /*===========================================================================
7321  * FUNCTION   : addAnalysisChannel
7322  *
7323  * DESCRIPTION: add a analysis channel that contains a analysis stream
7324  *
7325  * PARAMETERS : none
7326  *
7327  * RETURN     : int32_t type of status
7328  *              NO_ERROR  -- success
7329  *              none-zero failure code
7330  *==========================================================================*/
addAnalysisChannel()7331 int32_t QCamera2HardwareInterface::addAnalysisChannel()
7332 {
7333     int32_t rc = NO_ERROR;
7334     QCameraChannel *pChannel = NULL;
7335 
7336     if (m_channels[QCAMERA_CH_TYPE_ANALYSIS] != NULL) {
7337         delete m_channels[QCAMERA_CH_TYPE_ANALYSIS];
7338         m_channels[QCAMERA_CH_TYPE_ANALYSIS] = NULL;
7339     }
7340 
7341     pChannel = new QCameraChannel(mCameraHandle->camera_handle,
7342                                   mCameraHandle->ops);
7343     if (NULL == pChannel) {
7344         LOGE("no mem for metadata channel");
7345         return NO_MEMORY;
7346     }
7347 
7348     rc = pChannel->init(NULL, NULL, this);
7349     if (rc != NO_ERROR) {
7350         LOGE("init Analysis channel failed, ret = %d", rc);
7351         delete pChannel;
7352         return rc;
7353     }
7354 
7355     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
7356                             NULL, this);
7357     if (rc != NO_ERROR) {
7358         LOGE("add Analysis stream failed, ret = %d", rc);
7359         delete pChannel;
7360         return rc;
7361     }
7362 
7363     m_channels[QCAMERA_CH_TYPE_ANALYSIS] = pChannel;
7364     return rc;
7365 }
7366 
7367 
7368 /*===========================================================================
7369  * FUNCTION   : getPPConfig
7370  *
7371  * DESCRIPTION: get Post processing configaration data
7372  *
7373  * PARAMETERS :
7374  * @pp config:  pp config structure pointer,
7375  * @curIndex:  current pp channel index
7376  * @multipass: Flag if multipass prcessing enabled.
7377  *
7378  * RETURN     : int32_t type of status
7379  *              NO_ERROR  -- success
7380  *              none-zero failure code
7381  *==========================================================================*/
getPPConfig(cam_pp_feature_config_t & pp_config,int8_t curIndex,bool multipass)7382 int32_t QCamera2HardwareInterface::getPPConfig(cam_pp_feature_config_t &pp_config,
7383         int8_t curIndex, bool multipass)
7384 {
7385     int32_t rc = NO_ERROR;
7386 
7387     if (multipass) {
7388         LOGW("Multi pass enabled. Total Pass = %d, cur index = %d",
7389                 mParameters.getReprocCount(), curIndex);
7390     }
7391 
7392     LOGH("Supported pproc feature mask = %x",
7393             gCamCapability[mCameraId]->qcom_supported_feature_mask);
7394     uint32_t feature_mask = gCamCapability[mCameraId]->qcom_supported_feature_mask;
7395     int32_t zoomLevel = mParameters.getParmZoomLevel();
7396     uint32_t rotation = mParameters.getJpegRotation();
7397     int32_t effect = mParameters.getEffectValue();
7398 
7399     pp_config.cur_reproc_count = curIndex + 1;
7400     pp_config.total_reproc_count = mParameters.getReprocCount();
7401 
7402     switch(curIndex) {
7403         case 0:
7404             //Configure feature mask for first pass of reprocessing
7405             //check if any effects are enabled
7406             if ((CAM_EFFECT_MODE_OFF != effect) &&
7407                 (feature_mask & CAM_QCOM_FEATURE_EFFECT)) {
7408                 pp_config.feature_mask |= CAM_QCOM_FEATURE_EFFECT;
7409                 pp_config.effect = effect;
7410             }
7411 
7412             //check for features that need to be enabled by default like sharpness
7413             //(if supported by hw).
7414             if ((feature_mask & CAM_QCOM_FEATURE_SHARPNESS) &&
7415                 !mParameters.isOptiZoomEnabled()) {
7416                 pp_config.feature_mask |= CAM_QCOM_FEATURE_SHARPNESS;
7417                 pp_config.sharpness = mParameters.getSharpness();
7418             }
7419 
7420             //check if zoom is enabled
7421             if ((zoomLevel > 0) && (feature_mask & CAM_QCOM_FEATURE_CROP)) {
7422                 pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
7423             }
7424 
7425             if (mParameters.isWNREnabled() &&
7426                 (feature_mask & CAM_QCOM_FEATURE_DENOISE2D)) {
7427                 pp_config.feature_mask |= CAM_QCOM_FEATURE_DENOISE2D;
7428                 pp_config.denoise2d.denoise_enable = 1;
7429                 pp_config.denoise2d.process_plates =
7430                         mParameters.getDenoiseProcessPlate(CAM_INTF_PARM_WAVELET_DENOISE);
7431             }
7432 
7433             if (isCACEnabled()) {
7434                 pp_config.feature_mask |= CAM_QCOM_FEATURE_CAC;
7435             }
7436 
7437             //check if rotation is required
7438             if ((feature_mask & CAM_QCOM_FEATURE_ROTATION) && (rotation > 0)) {
7439                 pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION;
7440                 if (rotation == 0) {
7441                     pp_config.rotation = ROTATE_0;
7442                 } else if (rotation == 90) {
7443                     pp_config.rotation = ROTATE_90;
7444                 } else if (rotation == 180) {
7445                     pp_config.rotation = ROTATE_180;
7446                 } else if (rotation == 270) {
7447                     pp_config.rotation = ROTATE_270;
7448                 }
7449             }
7450 
7451             if (mParameters.isHDREnabled()){
7452                 pp_config.feature_mask |= CAM_QCOM_FEATURE_HDR;
7453                 pp_config.hdr_param.hdr_enable = 1;
7454                 pp_config.hdr_param.hdr_need_1x = mParameters.isHDR1xFrameEnabled();
7455                 pp_config.hdr_param.hdr_mode = CAM_HDR_MODE_MULTIFRAME;
7456             } else {
7457                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_HDR;
7458                 pp_config.hdr_param.hdr_enable = 0;
7459             }
7460 
7461             //check if scaling is enabled
7462             if ((feature_mask & CAM_QCOM_FEATURE_SCALE) &&
7463                 mParameters.isReprocScaleEnabled() &&
7464                 mParameters.isUnderReprocScaling()){
7465                 pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
7466                 mParameters.getPicSizeFromAPK(
7467                         pp_config.scale_param.output_width,
7468                         pp_config.scale_param.output_height);
7469             }
7470 
7471             if(mParameters.isUbiFocusEnabled()) {
7472                 pp_config.feature_mask |= CAM_QCOM_FEATURE_UBIFOCUS;
7473             } else {
7474                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_UBIFOCUS;
7475             }
7476 
7477             if(mParameters.isUbiRefocus()) {
7478                 pp_config.feature_mask |= CAM_QCOM_FEATURE_REFOCUS;
7479                 pp_config.misc_buf_param.misc_buffer_index = 0;
7480             } else {
7481                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_REFOCUS;
7482             }
7483 
7484             if(mParameters.isChromaFlashEnabled()) {
7485                 pp_config.feature_mask |= CAM_QCOM_FEATURE_CHROMA_FLASH;
7486                 pp_config.flash_value = CAM_FLASH_ON;
7487             } else {
7488                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_CHROMA_FLASH;
7489             }
7490 
7491             if(mParameters.isOptiZoomEnabled() && (0 <= zoomLevel)) {
7492                 pp_config.feature_mask |= CAM_QCOM_FEATURE_OPTIZOOM;
7493                 pp_config.zoom_level = (uint8_t) zoomLevel;
7494             } else {
7495                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_OPTIZOOM;
7496             }
7497 
7498             if (mParameters.getofflineRAW()) {
7499                 pp_config.feature_mask |= CAM_QCOM_FEATURE_RAW_PROCESSING;
7500             }
7501 
7502             if (mParameters.isTruePortraitEnabled()) {
7503                 pp_config.feature_mask |= CAM_QCOM_FEATURE_TRUEPORTRAIT;
7504                 pp_config.misc_buf_param.misc_buffer_index = 0;
7505             } else {
7506                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_TRUEPORTRAIT;
7507             }
7508 
7509             if(mParameters.isStillMoreEnabled()) {
7510                 pp_config.feature_mask |= CAM_QCOM_FEATURE_STILLMORE;
7511             } else {
7512                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_STILLMORE;
7513             }
7514 
7515             if (mParameters.isOEMFeatEnabled()) {
7516                 pp_config.feature_mask |= CAM_OEM_FEATURE_1;
7517             }
7518 
7519             if (mParameters.getCDSMode() != CAM_CDS_MODE_OFF) {
7520                 if (feature_mask & CAM_QCOM_FEATURE_DSDN) {
7521                     pp_config.feature_mask |= CAM_QCOM_FEATURE_DSDN;
7522                 } else {
7523                     pp_config.feature_mask |= CAM_QCOM_FEATURE_CDS;
7524                 }
7525             }
7526 
7527             if ((multipass) &&
7528                     (m_postprocessor.getPPChannelCount() > 1)) {
7529                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_PP_PASS_2;
7530                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_ROTATION;
7531                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_CDS;
7532                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_DSDN;
7533                 pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
7534             } else {
7535                 pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
7536             }
7537 
7538             cam_dimension_t thumb_src_dim;
7539             cam_dimension_t thumb_dst_dim;
7540             mParameters.getThumbnailSize(&(thumb_dst_dim.width), &(thumb_dst_dim.height));
7541             mParameters.getStreamDimension(CAM_STREAM_TYPE_POSTVIEW,thumb_src_dim);
7542             if ((thumb_dst_dim.width != thumb_src_dim.width) ||
7543                     (thumb_dst_dim.height != thumb_src_dim.height)) {
7544                 if (thumb_dst_dim.width != 0 && thumb_dst_dim.height != 0) {
7545                     pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
7546                 }
7547             }
7548 
7549             break;
7550 
7551         case 1:
7552             //Configure feature mask for second pass of reprocessing
7553             pp_config.feature_mask |= CAM_QCOM_FEATURE_PP_PASS_2;
7554             if ((feature_mask & CAM_QCOM_FEATURE_ROTATION) && (rotation > 0)) {
7555                 pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION;
7556                 if (rotation == 0) {
7557                     pp_config.rotation = ROTATE_0;
7558                 } else if (rotation == 90) {
7559                     pp_config.rotation = ROTATE_90;
7560                 } else if (rotation == 180) {
7561                     pp_config.rotation = ROTATE_180;
7562                 } else if (rotation == 270) {
7563                     pp_config.rotation = ROTATE_270;
7564                 }
7565             }
7566             if (mParameters.getCDSMode() != CAM_CDS_MODE_OFF) {
7567                 if (feature_mask & CAM_QCOM_FEATURE_DSDN) {
7568                     pp_config.feature_mask |= CAM_QCOM_FEATURE_DSDN;
7569                 } else {
7570                     pp_config.feature_mask |= CAM_QCOM_FEATURE_CDS;
7571                 }
7572             }
7573             pp_config.feature_mask &= ~CAM_QCOM_FEATURE_RAW_PROCESSING;
7574             pp_config.feature_mask &= ~CAM_QCOM_FEATURE_METADATA_PROCESSING;
7575             break;
7576 
7577     }
7578     LOGH("pproc feature mask set = %x pass count = %d",
7579              pp_config.feature_mask, curIndex);
7580     return rc;
7581 }
7582 
7583 /*===========================================================================
7584  * FUNCTION   : addReprocChannel
7585  *
7586  * DESCRIPTION: add a reprocess channel that will do reprocess on frames
7587  *              coming from input channel
7588  *
7589  * PARAMETERS :
7590  *   @pInputChannel : ptr to input channel whose frames will be post-processed
7591  *   @cur_channel_index : Current channel index in multipass
7592  *
7593  * RETURN     : Ptr to the newly created channel obj. NULL if failed.
7594  *==========================================================================*/
addReprocChannel(QCameraChannel * pInputChannel,int8_t cur_channel_index)7595 QCameraReprocessChannel *QCamera2HardwareInterface::addReprocChannel(
7596         QCameraChannel *pInputChannel, int8_t cur_channel_index)
7597 {
7598     int32_t rc = NO_ERROR;
7599     QCameraReprocessChannel *pChannel = NULL;
7600     uint32_t burst_cnt = mParameters.getNumOfSnapshots();
7601 
7602     if (pInputChannel == NULL) {
7603         LOGE("input channel obj is NULL");
7604         return NULL;
7605     }
7606 
7607     pChannel = new QCameraReprocessChannel(mCameraHandle->camera_handle,
7608                                            mCameraHandle->ops);
7609     if (NULL == pChannel) {
7610         LOGE("no mem for reprocess channel");
7611         return NULL;
7612     }
7613 
7614     // Capture channel, only need snapshot and postview streams start together
7615     mm_camera_channel_attr_t attr;
7616     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
7617     attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
7618     attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
7619     rc = pChannel->init(&attr,
7620                         postproc_channel_cb_routine,
7621                         this);
7622     if (rc != NO_ERROR) {
7623         LOGE("init reprocess channel failed, ret = %d", rc);
7624         delete pChannel;
7625         return NULL;
7626     }
7627 
7628     // pp feature config
7629     cam_pp_feature_config_t pp_config;
7630     memset(&pp_config, 0, sizeof(cam_pp_feature_config_t));
7631 
7632     rc = getPPConfig(pp_config, cur_channel_index,
7633             ((mParameters.getReprocCount() > 1) ? TRUE : FALSE));
7634     if (rc != NO_ERROR){
7635         LOGE("Error while creating PP config");
7636         delete pChannel;
7637         return NULL;
7638     }
7639 
7640     uint8_t minStreamBufNum = getBufNumRequired(CAM_STREAM_TYPE_OFFLINE_PROC);
7641 
7642     //WNR and HDR happen inline. No extra buffers needed.
7643     uint32_t temp_feature_mask = pp_config.feature_mask;
7644     temp_feature_mask &= ~CAM_QCOM_FEATURE_HDR;
7645     if (temp_feature_mask && mParameters.isHDREnabled()) {
7646         minStreamBufNum = (uint8_t)(1 + mParameters.getNumOfExtraHDRInBufsIfNeeded());
7647     }
7648 
7649     if (mParameters.isStillMoreEnabled()) {
7650         cam_still_more_t stillmore_config = mParameters.getStillMoreSettings();
7651         pp_config.burst_cnt = stillmore_config.burst_count;
7652         LOGH("Stillmore burst %d", pp_config.burst_cnt);
7653 
7654         // getNumOfExtraBuffersForImageProc returns 1 less buffer assuming
7655         // number of capture is already added. In the case of liveshot,
7656         // stillmore burst is 1. This is to account for the premature decrement
7657         if (mParameters.getNumOfExtraBuffersForImageProc() == 0) {
7658             minStreamBufNum += 1;
7659         }
7660     }
7661 
7662     if (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_3) {
7663         minStreamBufNum += mParameters.getReprocCount() - 1;
7664         burst_cnt = mParameters.getReprocCount();
7665         if (cur_channel_index == 0) {
7666             pChannel->setReprocCount(2);
7667         } else {
7668             pChannel->setReprocCount(1);
7669         }
7670     } else {
7671         pChannel->setReprocCount(1);
7672     }
7673 
7674     // Add non inplace image lib buffers only when ppproc is present,
7675     // becuase pproc is non inplace and input buffers for img lib
7676     // are output for pproc and this number of extra buffers is required
7677     // If pproc is not there, input buffers for imglib are from snapshot stream
7678     uint8_t imglib_extra_bufs = mParameters.getNumOfExtraBuffersForImageProc();
7679     if (temp_feature_mask && imglib_extra_bufs) {
7680         // 1 is added because getNumOfExtraBuffersForImageProc returns extra
7681         // buffers assuming number of capture is already added
7682         minStreamBufNum = (uint8_t)(minStreamBufNum + imglib_extra_bufs + 1);
7683     }
7684 
7685     //Mask out features that are already processed in snapshot stream.
7686     uint32_t snapshot_feature_mask = 0;
7687     mParameters.getStreamPpMask(CAM_STREAM_TYPE_SNAPSHOT, snapshot_feature_mask);
7688 
7689     pp_config.feature_mask &= ~snapshot_feature_mask;
7690     LOGH("Snapshot feature mask: 0x%x, reproc feature mask: 0x%x",
7691             snapshot_feature_mask, pp_config.feature_mask);
7692 
7693     bool offlineReproc = isRegularCapture();
7694     if (m_postprocessor.mOfflineDataBufs != NULL) {
7695         offlineReproc = TRUE;
7696     }
7697 
7698     cam_padding_info_t paddingInfo = gCamCapability[mCameraId]->padding_info;
7699     paddingInfo.offset_info.offset_x = 0;
7700     paddingInfo.offset_info.offset_y = 0;
7701     rc = pChannel->addReprocStreamsFromSource(*this,
7702                                               pp_config,
7703                                               pInputChannel,
7704                                               minStreamBufNum,
7705                                               burst_cnt,
7706                                               &paddingInfo,
7707                                               mParameters,
7708                                               mLongshotEnabled,
7709                                               offlineReproc);
7710     if (rc != NO_ERROR) {
7711         delete pChannel;
7712         return NULL;
7713     }
7714 
7715     return pChannel;
7716 }
7717 
7718 /*===========================================================================
7719  * FUNCTION   : addOfflineReprocChannel
7720  *
7721  * DESCRIPTION: add a offline reprocess channel contains one reproc stream,
7722  *              that will do reprocess on frames coming from external images
7723  *
7724  * PARAMETERS :
7725  *   @img_config  : offline reporcess image info
7726  *   @pp_feature  : pp feature config
7727  *
7728  * RETURN     : int32_t type of status
7729  *              NO_ERROR  -- success
7730  *              none-zero failure code
7731  *==========================================================================*/
addOfflineReprocChannel(cam_pp_offline_src_config_t & img_config,cam_pp_feature_config_t & pp_feature,stream_cb_routine stream_cb,void * userdata)7732 QCameraReprocessChannel *QCamera2HardwareInterface::addOfflineReprocChannel(
7733                                             cam_pp_offline_src_config_t &img_config,
7734                                             cam_pp_feature_config_t &pp_feature,
7735                                             stream_cb_routine stream_cb,
7736                                             void *userdata)
7737 {
7738     int32_t rc = NO_ERROR;
7739     QCameraReprocessChannel *pChannel = NULL;
7740 
7741     pChannel = new QCameraReprocessChannel(mCameraHandle->camera_handle,
7742                                            mCameraHandle->ops);
7743     if (NULL == pChannel) {
7744         LOGE("no mem for reprocess channel");
7745         return NULL;
7746     }
7747 
7748     rc = pChannel->init(NULL, NULL, NULL);
7749     if (rc != NO_ERROR) {
7750         LOGE("init reprocess channel failed, ret = %d", rc);
7751         delete pChannel;
7752         return NULL;
7753     }
7754 
7755     QCameraHeapMemory *pStreamInfo = allocateStreamInfoBuf(CAM_STREAM_TYPE_OFFLINE_PROC);
7756     if (pStreamInfo == NULL) {
7757         LOGE("no mem for stream info buf");
7758         delete pChannel;
7759         return NULL;
7760     }
7761 
7762     cam_stream_info_t *streamInfoBuf = (cam_stream_info_t *)pStreamInfo->getPtr(0);
7763     memset(streamInfoBuf, 0, sizeof(cam_stream_info_t));
7764     streamInfoBuf->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC;
7765     streamInfoBuf->fmt = img_config.input_fmt;
7766     streamInfoBuf->dim = img_config.input_dim;
7767     streamInfoBuf->buf_planes = img_config.input_buf_planes;
7768     streamInfoBuf->streaming_mode = CAM_STREAMING_MODE_BURST;
7769     streamInfoBuf->num_of_burst = img_config.num_of_bufs;
7770 
7771     streamInfoBuf->reprocess_config.pp_type = CAM_OFFLINE_REPROCESS_TYPE;
7772     streamInfoBuf->reprocess_config.offline = img_config;
7773     streamInfoBuf->reprocess_config.pp_feature_config = pp_feature;
7774 
7775     rc = pChannel->addStream(*this,
7776             pStreamInfo, NULL, img_config.num_of_bufs,
7777             &gCamCapability[mCameraId]->padding_info,
7778             stream_cb, userdata, false);
7779 
7780     if (rc != NO_ERROR) {
7781         LOGE("add reprocess stream failed, ret = %d", rc);
7782         delete pChannel;
7783         return NULL;
7784     }
7785 
7786     return pChannel;
7787 }
7788 
7789 /*===========================================================================
7790  * FUNCTION   : addChannel
7791  *
7792  * DESCRIPTION: add a channel by its type
7793  *
7794  * PARAMETERS :
7795  *   @ch_type : channel type
7796  *
7797  * RETURN     : int32_t type of status
7798  *              NO_ERROR  -- success
7799  *              none-zero failure code
7800  *==========================================================================*/
addChannel(qcamera_ch_type_enum_t ch_type)7801 int32_t QCamera2HardwareInterface::addChannel(qcamera_ch_type_enum_t ch_type)
7802 {
7803     int32_t rc = UNKNOWN_ERROR;
7804     switch (ch_type) {
7805     case QCAMERA_CH_TYPE_ZSL:
7806         rc = addZSLChannel();
7807         break;
7808     case QCAMERA_CH_TYPE_CAPTURE:
7809         rc = addCaptureChannel();
7810         break;
7811     case QCAMERA_CH_TYPE_PREVIEW:
7812         rc = addPreviewChannel();
7813         break;
7814     case QCAMERA_CH_TYPE_VIDEO:
7815         rc = addVideoChannel();
7816         break;
7817     case QCAMERA_CH_TYPE_SNAPSHOT:
7818         rc = addSnapshotChannel();
7819         break;
7820     case QCAMERA_CH_TYPE_RAW:
7821         rc = addRawChannel();
7822         break;
7823     case QCAMERA_CH_TYPE_METADATA:
7824         rc = addMetaDataChannel();
7825         break;
7826     case QCAMERA_CH_TYPE_CALLBACK:
7827         rc = addCallbackChannel();
7828         break;
7829     case QCAMERA_CH_TYPE_ANALYSIS:
7830         rc = addAnalysisChannel();
7831         break;
7832     default:
7833         break;
7834     }
7835     return rc;
7836 }
7837 
7838 /*===========================================================================
7839  * FUNCTION   : delChannel
7840  *
7841  * DESCRIPTION: delete a channel by its type
7842  *
7843  * PARAMETERS :
7844  *   @ch_type : channel type
7845  *   @destroy : delete context as well
7846  *
7847  * RETURN     : int32_t type of status
7848  *              NO_ERROR  -- success
7849  *              none-zero failure code
7850  *==========================================================================*/
delChannel(qcamera_ch_type_enum_t ch_type,bool destroy)7851 int32_t QCamera2HardwareInterface::delChannel(qcamera_ch_type_enum_t ch_type,
7852                                               bool destroy)
7853 {
7854     if (m_channels[ch_type] != NULL) {
7855         if (destroy) {
7856             delete m_channels[ch_type];
7857             m_channels[ch_type] = NULL;
7858         } else {
7859             m_channels[ch_type]->deleteChannel();
7860         }
7861     }
7862 
7863     return NO_ERROR;
7864 }
7865 
7866 /*===========================================================================
7867  * FUNCTION   : startChannel
7868  *
7869  * DESCRIPTION: start a channel by its type
7870  *
7871  * PARAMETERS :
7872  *   @ch_type : channel type
7873  *
7874  * RETURN     : int32_t type of status
7875  *              NO_ERROR  -- success
7876  *              none-zero failure code
7877  *==========================================================================*/
startChannel(qcamera_ch_type_enum_t ch_type)7878 int32_t QCamera2HardwareInterface::startChannel(qcamera_ch_type_enum_t ch_type)
7879 {
7880     int32_t rc = UNKNOWN_ERROR;
7881     if (m_channels[ch_type] != NULL) {
7882         rc = m_channels[ch_type]->start();
7883     }
7884     return rc;
7885 }
7886 
7887 /*===========================================================================
7888  * FUNCTION   : stopChannel
7889  *
7890  * DESCRIPTION: stop a channel by its type
7891  *
7892  * PARAMETERS :
7893  *   @ch_type : channel type
7894  *
7895  * RETURN     : int32_t type of status
7896  *              NO_ERROR  -- success
7897  *              none-zero failure code
7898  *==========================================================================*/
stopChannel(qcamera_ch_type_enum_t ch_type)7899 int32_t QCamera2HardwareInterface::stopChannel(qcamera_ch_type_enum_t ch_type)
7900 {
7901     int32_t rc = UNKNOWN_ERROR;
7902     if (m_channels[ch_type] != NULL) {
7903         rc = m_channels[ch_type]->stop();
7904     }
7905 
7906     return rc;
7907 }
7908 
7909 /*===========================================================================
7910  * FUNCTION   : preparePreview
7911  *
7912  * DESCRIPTION: add channels needed for preview
7913  *
7914  * PARAMETERS : none
7915  *
7916  * RETURN     : int32_t type of status
7917  *              NO_ERROR  -- success
7918  *              none-zero failure code
7919  *==========================================================================*/
preparePreview()7920 int32_t QCamera2HardwareInterface::preparePreview()
7921 {
7922     ATRACE_CALL();
7923     int32_t rc = NO_ERROR;
7924 
7925     LOGI("E");
7926     rc = mParameters.setStreamConfigure(false, false, false);
7927     if (rc != NO_ERROR) {
7928         LOGE("setStreamConfigure failed %d", rc);
7929         return rc;
7930     }
7931 
7932     if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) {
7933         rc = addChannel(QCAMERA_CH_TYPE_ZSL);
7934         if (rc != NO_ERROR) {
7935             LOGE("failed!! rc = %d", rc);
7936             return rc;
7937         }
7938 
7939         if (mParameters.isUBWCEnabled()) {
7940             cam_format_t fmt;
7941             mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW, fmt);
7942             if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
7943                 rc = addChannel(QCAMERA_CH_TYPE_CALLBACK);
7944                 if (rc != NO_ERROR) {
7945                     delChannel(QCAMERA_CH_TYPE_ZSL);
7946                     LOGE("failed!! rc = %d", rc);
7947                     return rc;
7948                 }
7949             }
7950         }
7951 
7952         if (mParameters.getofflineRAW()) {
7953             addChannel(QCAMERA_CH_TYPE_RAW);
7954         }
7955     } else {
7956         bool recordingHint = mParameters.getRecordingHintValue();
7957         if(!isRdiMode() && recordingHint) {
7958             //stop face detection,longshot,etc if turned ON in Camera mode
7959 #ifndef VANILLA_HAL
7960             int32_t arg; //dummy arg
7961             if (isLongshotEnabled()) {
7962                 sendCommand(CAMERA_CMD_LONGSHOT_OFF, arg, arg);
7963             }
7964             if (mParameters.isFaceDetectionEnabled()
7965                     && (!mParameters.fdModeInVideo())) {
7966                 sendCommand(CAMERA_CMD_STOP_FACE_DETECTION, arg, arg);
7967             }
7968             if (mParameters.isHistogramEnabled()) {
7969                 sendCommand(CAMERA_CMD_HISTOGRAM_OFF, arg, arg);
7970             }
7971 #endif
7972             //Don't create snapshot channel for liveshot, if low power mode is set.
7973             //Use video stream instead.
7974             if (!isLowPowerMode()) {
7975                rc = addChannel(QCAMERA_CH_TYPE_SNAPSHOT);
7976                if (rc != NO_ERROR) {
7977                    return rc;
7978                }
7979             }
7980 
7981             rc = addChannel(QCAMERA_CH_TYPE_VIDEO);
7982             if (rc != NO_ERROR) {
7983                 delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
7984                 LOGE("failed!! rc = %d", rc);
7985                 return rc;
7986             }
7987         }
7988 
7989         rc = addChannel(QCAMERA_CH_TYPE_PREVIEW);
7990         if (!isRdiMode() && (rc != NO_ERROR)) {
7991             if (recordingHint) {
7992                 delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
7993                 delChannel(QCAMERA_CH_TYPE_VIDEO);
7994             }
7995         }
7996 
7997         if (mParameters.isUBWCEnabled() && !recordingHint) {
7998             cam_format_t fmt;
7999             mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW, fmt);
8000             if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
8001                 rc = addChannel(QCAMERA_CH_TYPE_CALLBACK);
8002                 if (rc != NO_ERROR) {
8003                     delChannel(QCAMERA_CH_TYPE_PREVIEW);
8004                     if (!isRdiMode()) {
8005                         delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
8006                         delChannel(QCAMERA_CH_TYPE_VIDEO);
8007                     }
8008                     LOGE("failed!! rc = %d", rc);
8009                     return rc;
8010                 }
8011             }
8012         }
8013 
8014         if (NO_ERROR != rc) {
8015             delChannel(QCAMERA_CH_TYPE_PREVIEW);
8016             LOGE("failed!! rc = %d", rc);
8017         }
8018     }
8019 
8020     LOGI("E rc = %d", rc);
8021     return rc;
8022 }
8023 
8024 /*===========================================================================
8025  * FUNCTION   : unpreparePreview
8026  *
8027  * DESCRIPTION: delete channels for preview
8028  *
8029  * PARAMETERS : none
8030  *
8031  * RETURN     : none
8032  *==========================================================================*/
unpreparePreview()8033 void QCamera2HardwareInterface::unpreparePreview()
8034 {
8035     delChannel(QCAMERA_CH_TYPE_ZSL);
8036     delChannel(QCAMERA_CH_TYPE_PREVIEW);
8037     delChannel(QCAMERA_CH_TYPE_VIDEO);
8038     delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
8039     delChannel(QCAMERA_CH_TYPE_CALLBACK);
8040     delChannel(QCAMERA_CH_TYPE_RAW);
8041 }
8042 
8043 /*===========================================================================
8044  * FUNCTION   : playShutter
8045  *
8046  * DESCRIPTION: send request to play shutter sound
8047  *
8048  * PARAMETERS : none
8049  *
8050  * RETURN     : none
8051  *==========================================================================*/
playShutter()8052 void QCamera2HardwareInterface::playShutter(){
8053      if (mNotifyCb == NULL ||
8054          msgTypeEnabledWithLock(CAMERA_MSG_SHUTTER) == 0){
8055          LOGD("shutter msg not enabled or NULL cb");
8056          return;
8057      }
8058      LOGH("CAMERA_MSG_SHUTTER ");
8059      qcamera_callback_argm_t cbArg;
8060      memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
8061      cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK;
8062      cbArg.msg_type = CAMERA_MSG_SHUTTER;
8063      cbArg.ext1 = 0;
8064      cbArg.ext2 = false;
8065      m_cbNotifier.notifyCallback(cbArg);
8066 }
8067 
8068 /*===========================================================================
8069  * FUNCTION   : getChannelByHandle
8070  *
8071  * DESCRIPTION: return a channel by its handle
8072  *
8073  * PARAMETERS :
8074  *   @channelHandle : channel handle
8075  *
8076  * RETURN     : a channel obj if found, NULL if not found
8077  *==========================================================================*/
getChannelByHandle(uint32_t channelHandle)8078 QCameraChannel *QCamera2HardwareInterface::getChannelByHandle(uint32_t channelHandle)
8079 {
8080     for(int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
8081         if (m_channels[i] != NULL &&
8082             m_channels[i]->getMyHandle() == channelHandle) {
8083             return m_channels[i];
8084         }
8085     }
8086 
8087     return NULL;
8088 }
8089 /*===========================================================================
8090  * FUNCTION   : needPreviewFDCallback
8091  *
8092  * DESCRIPTION: decides if needPreviewFDCallback
8093  *
8094  * PARAMETERS :
8095  *   @num_faces : number of faces
8096  *
8097  * RETURN     : bool type of status
8098  *              true  -- success
8099  *              fale -- failure code
8100  *==========================================================================*/
needPreviewFDCallback(uint8_t num_faces)8101 bool QCamera2HardwareInterface::needPreviewFDCallback(uint8_t num_faces)
8102 {
8103     if (num_faces == 0 && mNumPreviewFaces == 0) {
8104         return false;
8105     }
8106 
8107     return true;
8108 }
8109 
8110 /*===========================================================================
8111  * FUNCTION   : processFaceDetectionReuslt
8112  *
8113  * DESCRIPTION: process face detection reuslt
8114  *
8115  * PARAMETERS :
8116  *   @faces_data : ptr to face processing result struct
8117  *
8118  * RETURN     : int32_t type of status
8119  *              NO_ERROR  -- success
8120  *              none-zero failure code
8121  *==========================================================================*/
processFaceDetectionResult(cam_faces_data_t * faces_data)8122 int32_t QCamera2HardwareInterface::processFaceDetectionResult(cam_faces_data_t *faces_data)
8123 {
8124     if (!mParameters.isFaceDetectionEnabled()) {
8125         LOGH("FaceDetection not enabled, no ops here");
8126         return NO_ERROR;
8127     }
8128 
8129     qcamera_face_detect_type_t fd_type = faces_data->detection_data.fd_type;
8130     cam_face_detection_data_t *detect_data = &(faces_data->detection_data);
8131     if ((NULL == mDataCb) ||
8132         (fd_type == QCAMERA_FD_PREVIEW && !msgTypeEnabled(CAMERA_MSG_PREVIEW_METADATA)) ||
8133         (!needPreviewFDCallback(detect_data->num_faces_detected))
8134 #ifndef VANILLA_HAL
8135         || (fd_type == QCAMERA_FD_SNAPSHOT && !msgTypeEnabled(CAMERA_MSG_META_DATA))
8136 #endif
8137         ) {
8138         LOGH("metadata msgtype not enabled, no ops here");
8139         return NO_ERROR;
8140     }
8141 
8142     if ((fd_type == QCAMERA_FD_PREVIEW) && (detect_data->update_flag == FALSE)) {
8143         // Don't send callback to app if this is skipped by fd at backend
8144         return NO_ERROR;
8145     }
8146 
8147     cam_dimension_t display_dim;
8148     mParameters.getStreamDimension(CAM_STREAM_TYPE_PREVIEW, display_dim);
8149     if (display_dim.width <= 0 || display_dim.height <= 0) {
8150         LOGE("Invalid preview width or height (%d x %d)",
8151                display_dim.width, display_dim.height);
8152         return UNKNOWN_ERROR;
8153     }
8154 
8155     // process face detection result
8156     // need separate face detection in preview or snapshot type
8157     size_t faceResultSize = 0;
8158     size_t data_len = 0;
8159     if(fd_type == QCAMERA_FD_PREVIEW){
8160         //fd for preview frames
8161         faceResultSize = sizeof(camera_frame_metadata_t);
8162         faceResultSize += sizeof(camera_face_t) * MAX_ROI;
8163     }else if(fd_type == QCAMERA_FD_SNAPSHOT){
8164 #ifndef VANILLA_HAL
8165         // fd for snapshot frames
8166         //check if face is detected in this frame
8167         if(detect_data->num_faces_detected > 0){
8168             data_len = sizeof(camera_frame_metadata_t) +
8169                     sizeof(camera_face_t) * detect_data->num_faces_detected;
8170         }else{
8171             //no face
8172             data_len = 0;
8173         }
8174 #endif
8175         faceResultSize = 1 *sizeof(int)    //meta data type
8176                        + 1 *sizeof(int)    // meta data len
8177                        + data_len;         //data
8178     }
8179 
8180     camera_memory_t *faceResultBuffer = mGetMemory(-1,
8181                                                    faceResultSize,
8182                                                    1,
8183                                                    mCallbackCookie);
8184     if ( NULL == faceResultBuffer ) {
8185         LOGE("Not enough memory for face result data");
8186         return NO_MEMORY;
8187     }
8188 
8189     unsigned char *pFaceResult = ( unsigned char * ) faceResultBuffer->data;
8190     memset(pFaceResult, 0, faceResultSize);
8191     unsigned char *faceData = NULL;
8192     if(fd_type == QCAMERA_FD_PREVIEW){
8193         faceData = pFaceResult;
8194         mNumPreviewFaces = detect_data->num_faces_detected;
8195     }else if(fd_type == QCAMERA_FD_SNAPSHOT){
8196 #ifndef VANILLA_HAL
8197         //need fill meta type and meta data len first
8198         int *data_header = (int* )pFaceResult;
8199         data_header[0] = CAMERA_META_DATA_FD;
8200         data_header[1] = (int)data_len;
8201 
8202         if(data_len <= 0){
8203             //if face is not valid or do not have face, return
8204             qcamera_callback_argm_t cbArg;
8205             memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
8206             cbArg.cb_type = QCAMERA_DATA_CALLBACK;
8207             cbArg.msg_type = CAMERA_MSG_META_DATA;
8208             cbArg.data = faceResultBuffer;
8209             cbArg.user_data = faceResultBuffer;
8210             cbArg.cookie = this;
8211             cbArg.release_cb = releaseCameraMemory;
8212             int32_t rc = m_cbNotifier.notifyCallback(cbArg);
8213             if (rc != NO_ERROR) {
8214                 LOGE("fail sending notification");
8215                 faceResultBuffer->release(faceResultBuffer);
8216             }
8217             return rc;
8218         }
8219 #endif
8220         faceData = pFaceResult + 2 *sizeof(int); //skip two int length
8221     }
8222 
8223     camera_frame_metadata_t *roiData = (camera_frame_metadata_t * ) faceData;
8224     camera_face_t *faces = (camera_face_t *) ( faceData + sizeof(camera_frame_metadata_t) );
8225 
8226     roiData->number_of_faces = detect_data->num_faces_detected;
8227     roiData->faces = faces;
8228     if (roiData->number_of_faces > 0) {
8229         for (int i = 0; i < roiData->number_of_faces; i++) {
8230             faces[i].id = detect_data->faces[i].face_id;
8231             faces[i].score = detect_data->faces[i].score;
8232 
8233             // left
8234             faces[i].rect[0] = MAP_TO_DRIVER_COORDINATE(
8235                     detect_data->faces[i].face_boundary.left,
8236                     display_dim.width, 2000, -1000);
8237 
8238             // top
8239             faces[i].rect[1] = MAP_TO_DRIVER_COORDINATE(
8240                     detect_data->faces[i].face_boundary.top,
8241                     display_dim.height, 2000, -1000);
8242 
8243             // right
8244             faces[i].rect[2] = faces[i].rect[0] +
8245                     MAP_TO_DRIVER_COORDINATE(
8246                     detect_data->faces[i].face_boundary.width,
8247                     display_dim.width, 2000, 0);
8248 
8249              // bottom
8250             faces[i].rect[3] = faces[i].rect[1] +
8251                     MAP_TO_DRIVER_COORDINATE(
8252                     detect_data->faces[i].face_boundary.height,
8253                     display_dim.height, 2000, 0);
8254 
8255             if (faces_data->landmark_valid) {
8256                 // Center of left eye
8257                 faces[i].left_eye[0] = MAP_TO_DRIVER_COORDINATE(
8258                         faces_data->landmark_data.face_landmarks[i].left_eye_center.x,
8259                         display_dim.width, 2000, -1000);
8260                 faces[i].left_eye[1] = MAP_TO_DRIVER_COORDINATE(
8261                         faces_data->landmark_data.face_landmarks[i].left_eye_center.y,
8262                         display_dim.height, 2000, -1000);
8263 
8264                 // Center of right eye
8265                 faces[i].right_eye[0] = MAP_TO_DRIVER_COORDINATE(
8266                         faces_data->landmark_data.face_landmarks[i].right_eye_center.x,
8267                         display_dim.width, 2000, -1000);
8268                 faces[i].right_eye[1] = MAP_TO_DRIVER_COORDINATE(
8269                         faces_data->landmark_data.face_landmarks[i].right_eye_center.y,
8270                         display_dim.height, 2000, -1000);
8271 
8272                 // Center of mouth
8273                 faces[i].mouth[0] = MAP_TO_DRIVER_COORDINATE(
8274                         faces_data->landmark_data.face_landmarks[i].mouth_center.x,
8275                         display_dim.width, 2000, -1000);
8276                 faces[i].mouth[1] = MAP_TO_DRIVER_COORDINATE(
8277                         faces_data->landmark_data.face_landmarks[i].mouth_center.y,
8278                         display_dim.height, 2000, -1000);
8279             } else {
8280                 // return -2000 if invalid
8281                 faces[i].left_eye[0] = -2000;
8282                 faces[i].left_eye[1] = -2000;
8283 
8284                 faces[i].right_eye[0] = -2000;
8285                 faces[i].right_eye[1] = -2000;
8286 
8287                 faces[i].mouth[0] = -2000;
8288                 faces[i].mouth[1] = -2000;
8289             }
8290 
8291 #ifndef VANILLA_HAL
8292 #ifdef TARGET_TS_MAKEUP
8293             mFaceRect.left = detect_data->faces[i].face_boundary.left;
8294             mFaceRect.top = detect_data->faces[i].face_boundary.top;
8295             mFaceRect.right = detect_data->faces[i].face_boundary.width+mFaceRect.left;
8296             mFaceRect.bottom = detect_data->faces[i].face_boundary.height+mFaceRect.top;
8297 #endif
8298             if (faces_data->smile_valid) {
8299                 faces[i].smile_degree = faces_data->smile_data.smile[i].smile_degree;
8300                 faces[i].smile_score = faces_data->smile_data.smile[i].smile_confidence;
8301             }
8302             if (faces_data->blink_valid) {
8303                 faces[i].blink_detected = faces_data->blink_data.blink[i].blink_detected;
8304                 faces[i].leye_blink = faces_data->blink_data.blink[i].left_blink;
8305                 faces[i].reye_blink = faces_data->blink_data.blink[i].right_blink;
8306             }
8307             if (faces_data->recog_valid) {
8308                 faces[i].face_recognised = faces_data->recog_data.face_rec[i].face_recognised;
8309             }
8310             if (faces_data->gaze_valid) {
8311                 faces[i].gaze_angle = faces_data->gaze_data.gaze[i].gaze_angle;
8312                 faces[i].updown_dir = faces_data->gaze_data.gaze[i].updown_dir;
8313                 faces[i].leftright_dir = faces_data->gaze_data.gaze[i].leftright_dir;
8314                 faces[i].roll_dir = faces_data->gaze_data.gaze[i].roll_dir;
8315                 faces[i].left_right_gaze = faces_data->gaze_data.gaze[i].left_right_gaze;
8316                 faces[i].top_bottom_gaze = faces_data->gaze_data.gaze[i].top_bottom_gaze;
8317             }
8318 #endif
8319 
8320         }
8321     }
8322     else{
8323 #ifdef TARGET_TS_MAKEUP
8324         memset(&mFaceRect,-1,sizeof(mFaceRect));
8325 #endif
8326     }
8327     qcamera_callback_argm_t cbArg;
8328     memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
8329     cbArg.cb_type = QCAMERA_DATA_CALLBACK;
8330     if(fd_type == QCAMERA_FD_PREVIEW){
8331         cbArg.msg_type = CAMERA_MSG_PREVIEW_METADATA;
8332     }
8333 #ifndef VANILLA_HAL
8334     else if(fd_type == QCAMERA_FD_SNAPSHOT){
8335         cbArg.msg_type = CAMERA_MSG_META_DATA;
8336     }
8337 #endif
8338     cbArg.data = faceResultBuffer;
8339     cbArg.metadata = roiData;
8340     cbArg.user_data = faceResultBuffer;
8341     cbArg.cookie = this;
8342     cbArg.release_cb = releaseCameraMemory;
8343     int32_t rc = m_cbNotifier.notifyCallback(cbArg);
8344     if (rc != NO_ERROR) {
8345         LOGE("fail sending notification");
8346         faceResultBuffer->release(faceResultBuffer);
8347     }
8348 
8349     return rc;
8350 }
8351 
8352 /*===========================================================================
8353  * FUNCTION   : releaseCameraMemory
8354  *
8355  * DESCRIPTION: releases camera memory objects
8356  *
8357  * PARAMETERS :
8358  *   @data    : buffer to be released
8359  *   @cookie  : context data
8360  *   @cbStatus: callback status
8361  *
8362  * RETURN     : None
8363  *==========================================================================*/
releaseCameraMemory(void * data,void *,int32_t)8364 void QCamera2HardwareInterface::releaseCameraMemory(void *data,
8365                                                     void */*cookie*/,
8366                                                     int32_t /*cbStatus*/)
8367 {
8368     camera_memory_t *mem = ( camera_memory_t * ) data;
8369     if ( NULL != mem ) {
8370         mem->release(mem);
8371     }
8372 }
8373 
8374 /*===========================================================================
8375  * FUNCTION   : returnStreamBuffer
8376  *
8377  * DESCRIPTION: returns back a stream buffer
8378  *
8379  * PARAMETERS :
8380  *   @data    : buffer to be released
8381  *   @cookie  : context data
8382  *   @cbStatus: callback status
8383  *
8384  * RETURN     : None
8385  *==========================================================================*/
returnStreamBuffer(void * data,void * cookie,int32_t)8386 void QCamera2HardwareInterface::returnStreamBuffer(void *data,
8387                                                    void *cookie,
8388                                                    int32_t /*cbStatus*/)
8389 {
8390     QCameraStream *stream = ( QCameraStream * ) cookie;
8391     int idx = *((int *)data);
8392     if ((NULL != stream) && (0 <= idx)) {
8393         stream->bufDone((uint32_t)idx);
8394     } else {
8395         LOGE("Cannot return buffer %d %p", idx, cookie);
8396     }
8397 }
8398 
8399 /*===========================================================================
8400  * FUNCTION   : processHistogramStats
8401  *
8402  * DESCRIPTION: process histogram stats
8403  *
8404  * PARAMETERS :
8405  *   @hist_data : ptr to histogram stats struct
8406  *
8407  * RETURN     : int32_t type of status
8408  *              NO_ERROR  -- success
8409  *              none-zero failure code
8410  *==========================================================================*/
processHistogramStats(__unused cam_hist_stats_t & stats_data)8411 int32_t QCamera2HardwareInterface::processHistogramStats(
8412         __unused cam_hist_stats_t &stats_data)
8413 {
8414 #ifndef VANILLA_HAL
8415     if (!mParameters.isHistogramEnabled()) {
8416         LOGH("Histogram not enabled, no ops here");
8417         return NO_ERROR;
8418     }
8419 
8420     camera_memory_t *histBuffer = mGetMemory(-1,
8421                                              sizeof(cam_histogram_data_t),
8422                                              1,
8423                                              mCallbackCookie);
8424     if ( NULL == histBuffer ) {
8425         LOGE("Not enough memory for histogram data");
8426         return NO_MEMORY;
8427     }
8428 
8429     cam_histogram_data_t *pHistData = (cam_histogram_data_t *)histBuffer->data;
8430     if (pHistData == NULL) {
8431         LOGE("memory data ptr is NULL");
8432         return UNKNOWN_ERROR;
8433     }
8434 
8435     switch (stats_data.type) {
8436     case CAM_HISTOGRAM_TYPE_BAYER:
8437         *pHistData = stats_data.bayer_stats.gb_stats;
8438         break;
8439     case CAM_HISTOGRAM_TYPE_YUV:
8440         *pHistData = stats_data.yuv_stats;
8441         break;
8442     }
8443 
8444     qcamera_callback_argm_t cbArg;
8445     memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
8446     cbArg.cb_type = QCAMERA_DATA_CALLBACK;
8447     cbArg.msg_type = CAMERA_MSG_STATS_DATA;
8448     cbArg.data = histBuffer;
8449     cbArg.user_data = histBuffer;
8450     cbArg.cookie = this;
8451     cbArg.release_cb = releaseCameraMemory;
8452     int32_t rc = m_cbNotifier.notifyCallback(cbArg);
8453     if (rc != NO_ERROR) {
8454         LOGE("fail sending notification");
8455         histBuffer->release(histBuffer);
8456     }
8457 #endif
8458     return NO_ERROR;
8459 }
8460 
8461 /*===========================================================================
8462  * FUNCTION   : calcThermalLevel
8463  *
8464  * DESCRIPTION: Calculates the target fps range depending on
8465  *              the thermal level.
8466  *              Note that this function can be called from QCameraParametersIntf
8467  *              while mutex is held. So it should not call back into
8468  *              QCameraParametersIntf causing deadlock.
8469  *
8470  * PARAMETERS :
8471  *   @level      : received thermal level
8472  *   @minFPS     : minimum configured fps range
8473  *   @maxFPS     : maximum configured fps range
8474  *   @minVideoFps: minimum configured fps range
8475  *   @maxVideoFps: maximum configured fps range
8476  *   @adjustedRange : target fps range
8477  *   @skipPattern : target skip pattern
8478  *
8479  * RETURN     : int32_t type of status
8480  *              NO_ERROR  -- success
8481  *              none-zero failure code
8482  *==========================================================================*/
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)8483 int QCamera2HardwareInterface::calcThermalLevel(
8484             qcamera_thermal_level_enum_t level,
8485             const int minFPSi,
8486             const int maxFPSi,
8487             const float &minVideoFps,
8488             const float &maxVideoFps,
8489             cam_fps_range_t &adjustedRange,
8490             enum msm_vfe_frame_skip_pattern &skipPattern)
8491 {
8492     const float minFPS = (float)minFPSi;
8493     const float maxFPS = (float)maxFPSi;
8494 
8495     LOGH("level: %d, preview minfps %f, preview maxfpS %f, "
8496               "video minfps %f, video maxfpS %f",
8497              level, minFPS, maxFPS, minVideoFps, maxVideoFps);
8498 
8499     switch(level) {
8500     case QCAMERA_THERMAL_NO_ADJUSTMENT:
8501         {
8502             adjustedRange.min_fps = minFPS / 1000.0f;
8503             adjustedRange.max_fps = maxFPS / 1000.0f;
8504             adjustedRange.video_min_fps = minVideoFps / 1000.0f;
8505             adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
8506             skipPattern = NO_SKIP;
8507         }
8508         break;
8509     case QCAMERA_THERMAL_SLIGHT_ADJUSTMENT:
8510         {
8511             adjustedRange.min_fps = minFPS / 1000.0f;
8512             adjustedRange.max_fps = maxFPS / 1000.0f;
8513             adjustedRange.min_fps -= 0.1f * adjustedRange.min_fps;
8514             adjustedRange.max_fps -= 0.1f * adjustedRange.max_fps;
8515             adjustedRange.video_min_fps = minVideoFps / 1000.0f;
8516             adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
8517             adjustedRange.video_min_fps -= 0.1f * adjustedRange.video_min_fps;
8518             adjustedRange.video_max_fps -= 0.1f * adjustedRange.video_max_fps;
8519             if ( adjustedRange.min_fps < 1 ) {
8520                 adjustedRange.min_fps = 1;
8521             }
8522             if ( adjustedRange.max_fps < 1 ) {
8523                 adjustedRange.max_fps = 1;
8524             }
8525             if ( adjustedRange.video_min_fps < 1 ) {
8526                 adjustedRange.video_min_fps = 1;
8527             }
8528             if ( adjustedRange.video_max_fps < 1 ) {
8529                 adjustedRange.video_max_fps = 1;
8530             }
8531             skipPattern = EVERY_2FRAME;
8532         }
8533         break;
8534     case QCAMERA_THERMAL_BIG_ADJUSTMENT:
8535         {
8536             adjustedRange.min_fps = minFPS / 1000.0f;
8537             adjustedRange.max_fps = maxFPS / 1000.0f;
8538             adjustedRange.min_fps -= 0.2f * adjustedRange.min_fps;
8539             adjustedRange.max_fps -= 0.2f * adjustedRange.max_fps;
8540             adjustedRange.video_min_fps = minVideoFps / 1000.0f;
8541             adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
8542             adjustedRange.video_min_fps -= 0.2f * adjustedRange.video_min_fps;
8543             adjustedRange.video_max_fps -= 0.2f * adjustedRange.video_max_fps;
8544             if ( adjustedRange.min_fps < 1 ) {
8545                 adjustedRange.min_fps = 1;
8546             }
8547             if ( adjustedRange.max_fps < 1 ) {
8548                 adjustedRange.max_fps = 1;
8549             }
8550             if ( adjustedRange.video_min_fps < 1 ) {
8551                 adjustedRange.video_min_fps = 1;
8552             }
8553             if ( adjustedRange.video_max_fps < 1 ) {
8554                 adjustedRange.video_max_fps = 1;
8555             }
8556             skipPattern = EVERY_4FRAME;
8557         }
8558         break;
8559     case QCAMERA_THERMAL_MAX_ADJUSTMENT:
8560         {
8561             // Stop Preview?
8562             // Set lowest min FPS for now
8563             adjustedRange.min_fps = minFPS/1000.0f;
8564             adjustedRange.max_fps = minFPS/1000.0f;
8565             cam_capability_t *capability = gCamCapability[mCameraId];
8566             for (size_t i = 0;
8567                      i < capability->fps_ranges_tbl_cnt;
8568                      i++) {
8569                 if (capability->fps_ranges_tbl[i].min_fps <
8570                         adjustedRange.min_fps) {
8571                     adjustedRange.min_fps =
8572                             capability->fps_ranges_tbl[i].min_fps;
8573                     adjustedRange.max_fps = adjustedRange.min_fps;
8574                 }
8575             }
8576             skipPattern = MAX_SKIP;
8577             adjustedRange.video_min_fps = adjustedRange.min_fps;
8578             adjustedRange.video_max_fps = adjustedRange.max_fps;
8579         }
8580         break;
8581     case QCAMERA_THERMAL_SHUTDOWN:
8582         {
8583             // send error notify
8584             LOGE("Received shutdown thermal level. Closing camera");
8585             sendEvtNotify(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0);
8586         }
8587         break;
8588     default:
8589         {
8590             LOGW("Invalid thermal level %d", level);
8591             return BAD_VALUE;
8592         }
8593         break;
8594     }
8595 
8596     return NO_ERROR;
8597 }
8598 
8599 /*===========================================================================
8600  * FUNCTION   : recalcFPSRange
8601  *
8602  * DESCRIPTION: adjust the configured fps range regarding
8603  *              the last thermal level.
8604  *
8605  * PARAMETERS :
8606  *   @minFPS      : minimum configured fps range
8607  *   @maxFPS      : maximum configured fps range
8608  *   @minVideoFPS : minimum configured video fps
8609  *   @maxVideoFPS : maximum configured video fps
8610  *   @adjustedRange : target fps range
8611  *
8612  * RETURN     : int32_t type of status
8613  *              NO_ERROR  -- success
8614  *              none-zero failure code
8615  *==========================================================================*/
recalcFPSRange(int & minFPS,int & maxFPS,const float & minVideoFPS,const float & maxVideoFPS,cam_fps_range_t & adjustedRange)8616 int QCamera2HardwareInterface::recalcFPSRange(int &minFPS, int &maxFPS,
8617         const float &minVideoFPS, const float &maxVideoFPS,
8618         cam_fps_range_t &adjustedRange)
8619 {
8620     enum msm_vfe_frame_skip_pattern skipPattern;
8621     calcThermalLevel(mThermalLevel,
8622                      minFPS,
8623                      maxFPS,
8624                      minVideoFPS,
8625                      maxVideoFPS,
8626                      adjustedRange,
8627                      skipPattern);
8628     return NO_ERROR;
8629 }
8630 
8631 /*===========================================================================
8632  * FUNCTION   : updateThermalLevel
8633  *
8634  * DESCRIPTION: update thermal level depending on thermal events
8635  *
8636  * PARAMETERS :
8637  *   @level   : thermal level
8638  *
8639  * RETURN     : int32_t type of status
8640  *              NO_ERROR  -- success
8641  *              none-zero failure code
8642  *==========================================================================*/
updateThermalLevel(void * thermal_level)8643 int QCamera2HardwareInterface::updateThermalLevel(void *thermal_level)
8644 {
8645     int ret = NO_ERROR;
8646     cam_fps_range_t adjustedRange;
8647     int minFPS, maxFPS;
8648     float minVideoFPS, maxVideoFPS;
8649     enum msm_vfe_frame_skip_pattern skipPattern;
8650     qcamera_thermal_level_enum_t level = *(qcamera_thermal_level_enum_t *)thermal_level;
8651 
8652 
8653     if (!mCameraOpened) {
8654         LOGH("Camera is not opened, no need to update camera parameters");
8655         return NO_ERROR;
8656     }
8657     if (mParameters.getRecordingHintValue()) {
8658         LOGH("Thermal mitigation isn't enabled in camcorder mode");
8659         return NO_ERROR;
8660     }
8661 
8662     mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
8663     qcamera_thermal_mode thermalMode = mParameters.getThermalMode();
8664     if (mParameters.isHfrMode()) {
8665         cam_fps_range_t hfrFpsRange;
8666         mParameters.getHfrFps(hfrFpsRange);
8667         minVideoFPS = hfrFpsRange.video_min_fps;
8668         maxVideoFPS = hfrFpsRange.video_max_fps;
8669     } else {
8670         minVideoFPS = minFPS;
8671         maxVideoFPS = maxFPS;
8672     }
8673 
8674     calcThermalLevel(level, minFPS, maxFPS, minVideoFPS, maxVideoFPS,
8675             adjustedRange, skipPattern);
8676     mThermalLevel = level;
8677 
8678     if (thermalMode == QCAMERA_THERMAL_ADJUST_FPS)
8679         ret = mParameters.adjustPreviewFpsRange(&adjustedRange);
8680     else if (thermalMode == QCAMERA_THERMAL_ADJUST_FRAMESKIP)
8681         ret = mParameters.setFrameSkip(skipPattern);
8682     else
8683         LOGW("Incorrect thermal mode %d", thermalMode);
8684 
8685     return ret;
8686 
8687 }
8688 
8689 /*===========================================================================
8690  * FUNCTION   : updateParameters
8691  *
8692  * DESCRIPTION: update parameters
8693  *
8694  * PARAMETERS :
8695  *   @parms       : input parameters string
8696  *   @needRestart : output, flag to indicate if preview restart is needed
8697  *
8698  * RETURN     : int32_t type of status
8699  *              NO_ERROR  -- success
8700  *              none-zero failure code
8701  *==========================================================================*/
updateParameters(const char * parms,bool & needRestart)8702 int QCamera2HardwareInterface::updateParameters(const char *parms, bool &needRestart)
8703 {
8704     int rc = NO_ERROR;
8705 
8706     String8 str = String8(parms);
8707     rc =  mParameters.updateParameters(str, needRestart);
8708     setNeedRestart(needRestart);
8709 
8710     // update stream based parameter settings
8711     for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
8712         if (m_channels[i] != NULL) {
8713             m_channels[i]->UpdateStreamBasedParameters(mParameters);
8714         }
8715     }
8716 
8717     return rc;
8718 }
8719 
8720 /*===========================================================================
8721  * FUNCTION   : commitParameterChanges
8722  *
8723  * DESCRIPTION: commit parameter changes to the backend to take effect
8724  *
8725  * PARAMETERS : none
8726  *
8727  * RETURN     : int32_t type of status
8728  *              NO_ERROR  -- success
8729  *              none-zero failure code
8730  * NOTE       : This function must be called after updateParameters.
8731  *              Otherwise, no change will be passed to backend to take effect.
8732  *==========================================================================*/
commitParameterChanges()8733 int QCamera2HardwareInterface::commitParameterChanges()
8734 {
8735     int rc = NO_ERROR;
8736     rc = mParameters.commitParameters();
8737     if (rc == NO_ERROR) {
8738         // update number of snapshot based on committed parameters setting
8739         rc = mParameters.setNumOfSnapshot();
8740     }
8741     return rc;
8742 }
8743 
8744 /*===========================================================================
8745  * FUNCTION   : needDebugFps
8746  *
8747  * DESCRIPTION: if fps log info need to be printed out
8748  *
8749  * PARAMETERS : none
8750  *
8751  * RETURN     : true: need print out fps log
8752  *              false: no need to print out fps log
8753  *==========================================================================*/
needDebugFps()8754 bool QCamera2HardwareInterface::needDebugFps()
8755 {
8756     bool needFps = false;
8757     needFps = mParameters.isFpsDebugEnabled();
8758     return needFps;
8759 }
8760 
8761 /*===========================================================================
8762  * FUNCTION   : isCACEnabled
8763  *
8764  * DESCRIPTION: if CAC is enabled
8765  *
8766  * PARAMETERS : none
8767  *
8768  * RETURN     : true: needed
8769  *              false: no need
8770  *==========================================================================*/
isCACEnabled()8771 bool QCamera2HardwareInterface::isCACEnabled()
8772 {
8773     char prop[PROPERTY_VALUE_MAX];
8774     memset(prop, 0, sizeof(prop));
8775     property_get("persist.camera.feature.cac", prop, "0");
8776     int enableCAC = atoi(prop);
8777     return enableCAC == 1;
8778 }
8779 
8780 /*===========================================================================
8781  * FUNCTION   : is4k2kResolution
8782  *
8783  * DESCRIPTION: if resolution is 4k x 2k or true 4k x 2k
8784  *
8785  * PARAMETERS : none
8786  *
8787  * RETURN     : true: needed
8788  *              false: no need
8789  *==========================================================================*/
is4k2kResolution(cam_dimension_t * resolution)8790 bool QCamera2HardwareInterface::is4k2kResolution(cam_dimension_t* resolution)
8791 {
8792    bool enabled = false;
8793    if ((resolution->width == 4096 && resolution->height == 2160) ||
8794        (resolution->width == 3840 && resolution->height == 2160) ) {
8795       enabled = true;
8796    }
8797    return enabled;
8798 }
8799 
8800 /*===========================================================================
8801  * FUNCTION   : isPreviewRestartEnabled
8802  *
8803  * DESCRIPTION: Check whether preview should be restarted automatically
8804  *              during image capture.
8805  *
8806  * PARAMETERS : none
8807  *
8808  * RETURN     : true: needed
8809  *              false: no need
8810  *==========================================================================*/
isPreviewRestartEnabled()8811 bool QCamera2HardwareInterface::isPreviewRestartEnabled()
8812 {
8813     char prop[PROPERTY_VALUE_MAX];
8814     memset(prop, 0, sizeof(prop));
8815     property_get("persist.camera.feature.restart", prop, "0");
8816     int earlyRestart = atoi(prop);
8817     return earlyRestart == 1;
8818 }
8819 
8820 /*===========================================================================
8821  * FUNCTION   : needReprocess
8822  *
8823  * DESCRIPTION: if reprocess is needed
8824  *
8825  * PARAMETERS : none
8826  *
8827  * RETURN     : true: needed
8828  *              false: no need
8829  *==========================================================================*/
needReprocess()8830 bool QCamera2HardwareInterface::needReprocess()
8831 {
8832     bool needReprocess = false;
8833 
8834     if (!mParameters.isJpegPictureFormat() &&
8835         !mParameters.isNV21PictureFormat()) {
8836         // RAW image, no need to reprocess
8837         return false;
8838     }
8839 
8840     //Disable reprocess for 4K liveshot case but enable if lowpower mode
8841     if (mParameters.is4k2kVideoResolution() && mParameters.getRecordingHintValue()
8842             && !isLowPowerMode()) {
8843         return false;
8844     }
8845 
8846     // pp feature config
8847     cam_pp_feature_config_t pp_config;
8848     memset(&pp_config, 0, sizeof(cam_pp_feature_config_t));
8849 
8850     //Decide whether to do reprocess or not based on
8851     //ppconfig obtained in the first pass.
8852     getPPConfig(pp_config);
8853 
8854     if (pp_config.feature_mask > 0) {
8855         needReprocess = true;
8856     }
8857 
8858     LOGH("needReprocess %s", needReprocess ? "true" : "false");
8859     return needReprocess;
8860 }
8861 
8862 
8863 /*===========================================================================
8864  * FUNCTION   : needRotationReprocess
8865  *
8866  * DESCRIPTION: if rotation needs to be done by reprocess in pp
8867  *
8868  * PARAMETERS : none
8869  *
8870  * RETURN     : true: needed
8871  *              false: no need
8872  *==========================================================================*/
needRotationReprocess()8873 bool QCamera2HardwareInterface::needRotationReprocess()
8874 {
8875     if (!mParameters.isJpegPictureFormat() &&
8876         !mParameters.isNV21PictureFormat()) {
8877         // RAW image, no need to reprocess
8878         return false;
8879     }
8880 
8881     //Disable reprocess for 4K liveshot case
8882     if (mParameters.is4k2kVideoResolution() && mParameters.getRecordingHintValue()
8883             && !isLowPowerMode()) {
8884         //Disable reprocess for 4K liveshot case
8885         return false;
8886     }
8887 
8888     if ((gCamCapability[mCameraId]->qcom_supported_feature_mask &
8889             CAM_QCOM_FEATURE_ROTATION) > 0 &&
8890             (mParameters.getJpegRotation() > 0)) {
8891         // current rotation is not zero, and pp has the capability to process rotation
8892         LOGH("need to do reprocess for rotation=%d",
8893                  mParameters.getJpegRotation());
8894         return true;
8895     }
8896 
8897     return false;
8898 }
8899 
8900 /*===========================================================================
8901  * FUNCTION   : getThumbnailSize
8902  *
8903  * DESCRIPTION: get user set thumbnail size
8904  *
8905  * PARAMETERS :
8906  *   @dim     : output of thumbnail dimension
8907  *
8908  * RETURN     : none
8909  *==========================================================================*/
getThumbnailSize(cam_dimension_t & dim)8910 void QCamera2HardwareInterface::getThumbnailSize(cam_dimension_t &dim)
8911 {
8912     mParameters.getThumbnailSize(&dim.width, &dim.height);
8913 }
8914 
8915 /*===========================================================================
8916  * FUNCTION   : getJpegQuality
8917  *
8918  * DESCRIPTION: get user set jpeg quality
8919  *
8920  * PARAMETERS : none
8921  *
8922  * RETURN     : jpeg quality setting
8923  *==========================================================================*/
getJpegQuality()8924 uint32_t QCamera2HardwareInterface::getJpegQuality()
8925 {
8926     uint32_t quality = 0;
8927     quality =  mParameters.getJpegQuality();
8928     return quality;
8929 }
8930 
8931 /*===========================================================================
8932  * FUNCTION   : getExifData
8933  *
8934  * DESCRIPTION: get exif data to be passed into jpeg encoding
8935  *
8936  * PARAMETERS : none
8937  *
8938  * RETURN     : exif data from user setting and GPS
8939  *==========================================================================*/
getExifData()8940 QCameraExif *QCamera2HardwareInterface::getExifData()
8941 {
8942     QCameraExif *exif = new QCameraExif();
8943     if (exif == NULL) {
8944         LOGE("No memory for QCameraExif");
8945         return NULL;
8946     }
8947 
8948     int32_t rc = NO_ERROR;
8949 
8950     // add exif entries
8951     String8 dateTime, subSecTime;
8952     rc = mParameters.getExifDateTime(dateTime, subSecTime);
8953     if(rc == NO_ERROR) {
8954         exif->addEntry(EXIFTAGID_DATE_TIME, EXIF_ASCII,
8955                 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string());
8956         exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, EXIF_ASCII,
8957                 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string());
8958         exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_DIGITIZED, EXIF_ASCII,
8959                 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string());
8960         exif->addEntry(EXIFTAGID_SUBSEC_TIME, EXIF_ASCII,
8961                 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string());
8962         exif->addEntry(EXIFTAGID_SUBSEC_TIME_ORIGINAL, EXIF_ASCII,
8963                 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string());
8964         exif->addEntry(EXIFTAGID_SUBSEC_TIME_DIGITIZED, EXIF_ASCII,
8965                 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string());
8966     } else {
8967         LOGW("getExifDateTime failed");
8968     }
8969 
8970     rat_t focalLength;
8971     rc = mParameters.getExifFocalLength(&focalLength);
8972     if (rc == NO_ERROR) {
8973         exif->addEntry(EXIFTAGID_FOCAL_LENGTH,
8974                        EXIF_RATIONAL,
8975                        1,
8976                        (void *)&(focalLength));
8977     } else {
8978         LOGW("getExifFocalLength failed");
8979     }
8980 
8981     uint16_t isoSpeed = mParameters.getExifIsoSpeed();
8982     if (getSensorType() != CAM_SENSOR_YUV) {
8983         exif->addEntry(EXIFTAGID_ISO_SPEED_RATING,
8984                        EXIF_SHORT,
8985                        1,
8986                        (void *)&(isoSpeed));
8987     }
8988 
8989     char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE];
8990     uint32_t count = 0;
8991 
8992     /*gps data might not be available */
8993     rc = mParameters.getExifGpsProcessingMethod(gpsProcessingMethod, count);
8994     if(rc == NO_ERROR) {
8995         exif->addEntry(EXIFTAGID_GPS_PROCESSINGMETHOD,
8996                        EXIF_ASCII,
8997                        count,
8998                        (void *)gpsProcessingMethod);
8999     } else {
9000         LOGW("getExifGpsProcessingMethod failed");
9001     }
9002 
9003     rat_t latitude[3];
9004     char latRef[2];
9005     rc = mParameters.getExifLatitude(latitude, latRef);
9006     if(rc == NO_ERROR) {
9007         exif->addEntry(EXIFTAGID_GPS_LATITUDE,
9008                        EXIF_RATIONAL,
9009                        3,
9010                        (void *)latitude);
9011         exif->addEntry(EXIFTAGID_GPS_LATITUDE_REF,
9012                        EXIF_ASCII,
9013                        2,
9014                        (void *)latRef);
9015     } else {
9016         LOGW("getExifLatitude failed");
9017     }
9018 
9019     rat_t longitude[3];
9020     char lonRef[2];
9021     rc = mParameters.getExifLongitude(longitude, lonRef);
9022     if(rc == NO_ERROR) {
9023         exif->addEntry(EXIFTAGID_GPS_LONGITUDE,
9024                        EXIF_RATIONAL,
9025                        3,
9026                        (void *)longitude);
9027 
9028         exif->addEntry(EXIFTAGID_GPS_LONGITUDE_REF,
9029                        EXIF_ASCII,
9030                        2,
9031                        (void *)lonRef);
9032     } else {
9033         LOGW("getExifLongitude failed");
9034     }
9035 
9036     rat_t altitude;
9037     char altRef;
9038     rc = mParameters.getExifAltitude(&altitude, &altRef);
9039     if(rc == NO_ERROR) {
9040         exif->addEntry(EXIFTAGID_GPS_ALTITUDE,
9041                        EXIF_RATIONAL,
9042                        1,
9043                        (void *)&(altitude));
9044 
9045         exif->addEntry(EXIFTAGID_GPS_ALTITUDE_REF,
9046                        EXIF_BYTE,
9047                        1,
9048                        (void *)&altRef);
9049     } else {
9050         LOGW("getExifAltitude failed");
9051     }
9052 
9053     char gpsDateStamp[20];
9054     rat_t gpsTimeStamp[3];
9055     rc = mParameters.getExifGpsDateTimeStamp(gpsDateStamp, 20, gpsTimeStamp);
9056     if(rc == NO_ERROR) {
9057         exif->addEntry(EXIFTAGID_GPS_DATESTAMP,
9058                        EXIF_ASCII,
9059                        (uint32_t)(strlen(gpsDateStamp) + 1),
9060                        (void *)gpsDateStamp);
9061 
9062         exif->addEntry(EXIFTAGID_GPS_TIMESTAMP,
9063                        EXIF_RATIONAL,
9064                        3,
9065                        (void *)gpsTimeStamp);
9066     } else {
9067         LOGW("getExifGpsDataTimeStamp failed");
9068     }
9069 
9070 #ifdef ENABLE_MODEL_INFO_EXIF
9071 
9072     char value[PROPERTY_VALUE_MAX];
9073     if (property_get("persist.sys.exif.make", value, "") > 0 ||
9074             property_get("ro.product.manufacturer", value, "QCOM-AA") > 0) {
9075         exif->addEntry(EXIFTAGID_MAKE,
9076                 EXIF_ASCII, strlen(value) + 1, (void *)value);
9077     } else {
9078         LOGW("getExifMaker failed");
9079     }
9080 
9081     if (property_get("persist.sys.exif.model", value, "") > 0 ||
9082             property_get("ro.product.model", value, "QCAM-AA") > 0) {
9083         exif->addEntry(EXIFTAGID_MODEL,
9084                 EXIF_ASCII, strlen(value) + 1, (void *)value);
9085     } else {
9086         LOGW("getExifModel failed");
9087     }
9088 
9089     if (property_get("ro.build.description", value, "QCAM-AA") > 0) {
9090         exif->addEntry(EXIFTAGID_SOFTWARE, EXIF_ASCII,
9091                 (uint32_t)(strlen(value) + 1), (void *)value);
9092     } else {
9093         LOGW("getExifSoftware failed");
9094     }
9095 
9096 #endif
9097 
9098     if (mParameters.useJpegExifRotation()) {
9099         int16_t orientation;
9100         switch (mParameters.getJpegExifRotation()) {
9101         case 0:
9102             orientation = 1;
9103             break;
9104         case 90:
9105             orientation = 6;
9106             break;
9107         case 180:
9108             orientation = 3;
9109             break;
9110         case 270:
9111             orientation = 8;
9112             break;
9113         default:
9114             orientation = 1;
9115             break;
9116         }
9117         exif->addEntry(EXIFTAGID_ORIENTATION,
9118                 EXIF_SHORT,
9119                 1,
9120                 (void *)&orientation);
9121         exif->addEntry(EXIFTAGID_TN_ORIENTATION,
9122                 EXIF_SHORT,
9123                 1,
9124                 (void *)&orientation);
9125     }
9126 
9127     return exif;
9128 }
9129 
9130 /*===========================================================================
9131  * FUNCTION   : setHistogram
9132  *
9133  * DESCRIPTION: set if histogram should be enabled
9134  *
9135  * PARAMETERS :
9136  *   @histogram_en : bool flag if histogram should be enabled
9137  *
9138  * RETURN     : int32_t type of status
9139  *              NO_ERROR  -- success
9140  *              none-zero failure code
9141  *==========================================================================*/
setHistogram(bool histogram_en)9142 int32_t QCamera2HardwareInterface::setHistogram(bool histogram_en)
9143 {
9144     return mParameters.setHistogram(histogram_en);
9145 }
9146 
9147 /*===========================================================================
9148  * FUNCTION   : setFaceDetection
9149  *
9150  * DESCRIPTION: set if face detection should be enabled
9151  *
9152  * PARAMETERS :
9153  *   @enabled : bool flag if face detection should be enabled
9154  *
9155  * RETURN     : int32_t type of status
9156  *              NO_ERROR  -- success
9157  *              none-zero failure code
9158  *==========================================================================*/
setFaceDetection(bool enabled)9159 int32_t QCamera2HardwareInterface::setFaceDetection(bool enabled)
9160 {
9161     return mParameters.setFaceDetection(enabled, true);
9162 }
9163 
9164 /*===========================================================================
9165  * FUNCTION   : isCaptureShutterEnabled
9166  *
9167  * DESCRIPTION: Check whether shutter should be triggered immediately after
9168  *              capture
9169  *
9170  * PARAMETERS :
9171  *
9172  * RETURN     : true - regular capture
9173  *              false - other type of capture
9174  *==========================================================================*/
isCaptureShutterEnabled()9175 bool QCamera2HardwareInterface::isCaptureShutterEnabled()
9176 {
9177     char prop[PROPERTY_VALUE_MAX];
9178     memset(prop, 0, sizeof(prop));
9179     property_get("persist.camera.feature.shutter", prop, "0");
9180     int enableShutter = atoi(prop);
9181     return enableShutter == 1;
9182 }
9183 
9184 /*===========================================================================
9185  * FUNCTION   : needProcessPreviewFrame
9186  *
9187  * DESCRIPTION: returns whether preview frame need to be displayed
9188  *
9189  * PARAMETERS :
9190  *   @frameID : frameID of frame to be processed
9191  *
9192  * RETURN     : int32_t type of status
9193  *              NO_ERROR  -- success
9194  *              none-zero failure code
9195  *==========================================================================*/
needProcessPreviewFrame(uint32_t frameID)9196 bool QCamera2HardwareInterface::needProcessPreviewFrame(uint32_t frameID)
9197 {
9198     return ((m_stateMachine.isPreviewRunning()) &&
9199             (!isDisplayFrameToSkip(frameID)) &&
9200             (!mParameters.isInstantAECEnabled()));
9201 }
9202 
9203 /*===========================================================================
9204  * FUNCTION   : needSendPreviewCallback
9205  *
9206  * DESCRIPTION: returns whether preview frame need to callback to APP
9207  *
9208  * PARAMETERS :
9209  *
9210  * RETURN     : true - need preview frame callbck
9211  *              false - not send preview frame callback
9212  *==========================================================================*/
needSendPreviewCallback()9213 bool QCamera2HardwareInterface::needSendPreviewCallback()
9214 {
9215     return m_stateMachine.isPreviewRunning()
9216             && (mDataCb != NULL)
9217             && (msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_FRAME) > 0)
9218             && m_stateMachine.isPreviewCallbackNeeded();
9219 };
9220 
9221 /*===========================================================================
9222  * FUNCTION   : setDisplaySkip
9223  *
9224  * DESCRIPTION: set range of frames to skip for preview
9225  *
9226  * PARAMETERS :
9227  *   @enabled : TRUE to start skipping frame to display
9228                 FALSE to stop skipping frame to display
9229  *   @skipCnt : Number of frame to skip. 0 by default
9230  *
9231  * RETURN     : None
9232  *==========================================================================*/
setDisplaySkip(bool enabled,uint8_t skipCnt)9233 void QCamera2HardwareInterface::setDisplaySkip(bool enabled, uint8_t skipCnt)
9234 {
9235     pthread_mutex_lock(&mGrallocLock);
9236     if (enabled) {
9237         setDisplayFrameSkip();
9238         setDisplayFrameSkip(mLastPreviewFrameID + skipCnt + 1);
9239     } else {
9240         setDisplayFrameSkip(mFrameSkipStart, (mLastPreviewFrameID + skipCnt + 1));
9241     }
9242     pthread_mutex_unlock(&mGrallocLock);
9243 }
9244 
9245 /*===========================================================================
9246  * FUNCTION   : setDisplayFrameSkip
9247  *
9248  * DESCRIPTION: set range of frames to skip for preview
9249  *
9250  * PARAMETERS :
9251  *   @start   : frameId to start skip
9252  *   @end     : frameId to stop skip
9253  *
9254  * RETURN     : None
9255  *==========================================================================*/
setDisplayFrameSkip(uint32_t start,uint32_t end)9256 void QCamera2HardwareInterface::setDisplayFrameSkip(uint32_t start,
9257         uint32_t end)
9258 {
9259     if (start == 0) {
9260         mFrameSkipStart = 0;
9261         mFrameSkipEnd = 0;
9262         return;
9263     }
9264     if ((mFrameSkipStart == 0) || (mFrameSkipStart > start)) {
9265         mFrameSkipStart = start;
9266     }
9267     if ((end == 0) || (end > mFrameSkipEnd)) {
9268         mFrameSkipEnd = end;
9269     }
9270 }
9271 
9272 /*===========================================================================
9273  * FUNCTION   : isDisplayFrameToSkip
9274  *
9275  * DESCRIPTION: function to determin if input frame falls under skip range
9276  *
9277  * PARAMETERS :
9278  *   @frameId : frameId to verify
9279  *
9280  * RETURN     : true : need to skip
9281  *              false: no need to skip
9282  *==========================================================================*/
isDisplayFrameToSkip(uint32_t frameId)9283 bool QCamera2HardwareInterface::isDisplayFrameToSkip(uint32_t frameId)
9284 {
9285     return ((mFrameSkipStart != 0) && (frameId >= mFrameSkipStart) &&
9286             (frameId <= mFrameSkipEnd || mFrameSkipEnd == 0)) ? TRUE : FALSE;
9287 }
9288 
9289 /*===========================================================================
9290  * FUNCTION   : prepareHardwareForSnapshot
9291  *
9292  * DESCRIPTION: prepare hardware for snapshot, such as LED
9293  *
9294  * PARAMETERS :
9295  *   @afNeeded: flag indicating if Auto Focus needs to be done during preparation
9296  *
9297  * RETURN     : int32_t type of status
9298  *              NO_ERROR  -- success
9299  *              none-zero failure code
9300  *==========================================================================*/
prepareHardwareForSnapshot(int32_t afNeeded)9301 int32_t QCamera2HardwareInterface::prepareHardwareForSnapshot(int32_t afNeeded)
9302 {
9303     ATRACE_CALL();
9304     LOGI("[KPI Perf]: Send PREPARE SANSPHOT event");
9305     return mCameraHandle->ops->prepare_snapshot(mCameraHandle->camera_handle,
9306                                                 afNeeded);
9307 }
9308 
9309 /*===========================================================================
9310  * FUNCTION   : needFDMetadata
9311  *
9312  * DESCRIPTION: check whether we need process Face Detection metadata in this chanel
9313  *
9314  * PARAMETERS :
9315  *   @channel_type: channel type
9316  *
9317   * RETURN     : true: needed
9318  *              false: no need
9319  *==========================================================================*/
needFDMetadata(qcamera_ch_type_enum_t channel_type)9320 bool QCamera2HardwareInterface::needFDMetadata(qcamera_ch_type_enum_t channel_type)
9321 {
9322     //Note: Currently we only process ZSL channel
9323     bool value = false;
9324     if(channel_type == QCAMERA_CH_TYPE_ZSL){
9325         //check if FD requirement is enabled
9326         if(mParameters.isSnapshotFDNeeded() &&
9327            mParameters.isFaceDetectionEnabled()){
9328             value = true;
9329             LOGH("Face Detection metadata is required in ZSL mode.");
9330         }
9331     }
9332 
9333     return value;
9334 }
9335 
9336 /*===========================================================================
9337  * FUNCTION   : deferredWorkRoutine
9338  *
9339  * DESCRIPTION: data process routine that executes deferred tasks
9340  *
9341  * PARAMETERS :
9342  *   @data    : user data ptr (QCamera2HardwareInterface)
9343  *
9344  * RETURN     : None
9345  *==========================================================================*/
deferredWorkRoutine(void * obj)9346 void *QCamera2HardwareInterface::deferredWorkRoutine(void *obj)
9347 {
9348     int running = 1;
9349     int ret;
9350     uint8_t is_active = FALSE;
9351     int32_t job_status = 0;
9352 
9353     QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)obj;
9354     QCameraCmdThread *cmdThread = &pme->mDeferredWorkThread;
9355     cmdThread->setName("CAM_defrdWrk");
9356 
9357     do {
9358         do {
9359             ret = cam_sem_wait(&cmdThread->cmd_sem);
9360             if (ret != 0 && errno != EINVAL) {
9361                 LOGE("cam_sem_wait error (%s)",
9362                          strerror(errno));
9363                 return NULL;
9364             }
9365         } while (ret != 0);
9366 
9367         // we got notified about new cmd avail in cmd queue
9368         camera_cmd_type_t cmd = cmdThread->getCmd();
9369         LOGD("cmd: %d", cmd);
9370         switch (cmd) {
9371         case CAMERA_CMD_TYPE_START_DATA_PROC:
9372             LOGH("start data proc");
9373             is_active = TRUE;
9374             break;
9375         case CAMERA_CMD_TYPE_STOP_DATA_PROC:
9376             LOGH("stop data proc");
9377             is_active = FALSE;
9378             // signal cmd is completed
9379             cam_sem_post(&cmdThread->sync_sem);
9380             break;
9381         case CAMERA_CMD_TYPE_DO_NEXT_JOB:
9382             {
9383                 DefWork *dw =
9384                     reinterpret_cast<DefWork *>(pme->mCmdQueue.dequeue());
9385 
9386                 if ( NULL == dw ) {
9387                     LOGE("Invalid deferred work");
9388                     break;
9389                 }
9390 
9391                 switch( dw->cmd ) {
9392                 case CMD_DEF_ALLOCATE_BUFF:
9393                     {
9394                         QCameraChannel * pChannel = dw->args.allocArgs.ch;
9395 
9396                         if ( NULL == pChannel ) {
9397                             LOGE("Invalid deferred work channel");
9398                             job_status = BAD_VALUE;
9399                             break;
9400                         }
9401 
9402                         cam_stream_type_t streamType = dw->args.allocArgs.type;
9403                         LOGH("Deferred buffer allocation started for stream type: %d",
9404                                  streamType);
9405 
9406                         uint32_t iNumOfStreams = pChannel->getNumOfStreams();
9407                         QCameraStream *pStream = NULL;
9408                         for ( uint32_t i = 0; i < iNumOfStreams; ++i) {
9409                             pStream = pChannel->getStreamByIndex(i);
9410 
9411                             if ( NULL == pStream ) {
9412                                 job_status = BAD_VALUE;
9413                                 break;
9414                             }
9415 
9416                             if ( pStream->isTypeOf(streamType)) {
9417                                 if ( pStream->allocateBuffers() ) {
9418                                     LOGE("Error allocating buffers !!!");
9419                                     job_status =  NO_MEMORY;
9420                                     pme->sendEvtNotify(CAMERA_MSG_ERROR,
9421                                             CAMERA_ERROR_UNKNOWN, 0);
9422                                 }
9423                                 break;
9424                             }
9425                         }
9426                     }
9427                     break;
9428                 case CMD_DEF_PPROC_START:
9429                     {
9430                         int32_t ret = pme->getDefJobStatus(pme->mInitPProcJob);
9431                         if (ret != NO_ERROR) {
9432                             job_status = ret;
9433                             LOGE("PPROC Start failed");
9434                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
9435                                     CAMERA_ERROR_UNKNOWN, 0);
9436                             break;
9437                         }
9438                         QCameraChannel * pChannel = dw->args.pprocArgs;
9439                         assert(pChannel);
9440 
9441                         if (pme->m_postprocessor.start(pChannel) != NO_ERROR) {
9442                             LOGE("cannot start postprocessor");
9443                             job_status = BAD_VALUE;
9444                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
9445                                     CAMERA_ERROR_UNKNOWN, 0);
9446                         }
9447                     }
9448                     break;
9449                 case CMD_DEF_METADATA_ALLOC:
9450                     {
9451                         int32_t ret = pme->getDefJobStatus(pme->mParamAllocJob);
9452                         if (ret != NO_ERROR) {
9453                             job_status = ret;
9454                             LOGE("Metadata alloc failed");
9455                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
9456                                     CAMERA_ERROR_UNKNOWN, 0);
9457                             break;
9458                         }
9459                         pme->mMetadataMem = new QCameraMetadataStreamMemory(
9460                                 QCAMERA_ION_USE_CACHE);
9461 
9462                         if (pme->mMetadataMem == NULL) {
9463                             LOGE("Unable to allocate metadata buffers");
9464                             job_status = BAD_VALUE;
9465                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
9466                                     CAMERA_ERROR_UNKNOWN, 0);
9467                         } else {
9468                             int32_t rc = pme->mMetadataMem->allocate(
9469                                     dw->args.metadataAllocArgs.bufferCnt,
9470                                     dw->args.metadataAllocArgs.size,
9471                                     NON_SECURE);
9472                             if (rc < 0) {
9473                                 delete pme->mMetadataMem;
9474                                 pme->mMetadataMem = NULL;
9475                             }
9476                         }
9477                      }
9478                      break;
9479                 case CMD_DEF_CREATE_JPEG_SESSION:
9480                     {
9481                         QCameraChannel * pChannel = dw->args.pprocArgs;
9482                         assert(pChannel);
9483 
9484                         int32_t ret = pme->getDefJobStatus(pme->mReprocJob);
9485                         if (ret != NO_ERROR) {
9486                             job_status = ret;
9487                             LOGE("Jpeg create failed");
9488                             break;
9489                         }
9490 
9491                         if (pme->m_postprocessor.createJpegSession(pChannel)
9492                             != NO_ERROR) {
9493                             LOGE("cannot create JPEG session");
9494                             job_status = UNKNOWN_ERROR;
9495                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
9496                                     CAMERA_ERROR_UNKNOWN, 0);
9497                         }
9498                     }
9499                     break;
9500                 case CMD_DEF_PPROC_INIT:
9501                     {
9502                         int32_t rc = NO_ERROR;
9503 
9504                         jpeg_encode_callback_t jpegEvtHandle =
9505                                 dw->args.pprocInitArgs.jpeg_cb;
9506                         void* user_data = dw->args.pprocInitArgs.user_data;
9507                         QCameraPostProcessor *postProcessor =
9508                                 &(pme->m_postprocessor);
9509                         uint32_t cameraId = pme->mCameraId;
9510                         cam_capability_t *capability =
9511                                 gCamCapability[cameraId];
9512                         cam_padding_info_t padding_info;
9513                         cam_padding_info_t& cam_capability_padding_info =
9514                                 capability->padding_info;
9515 
9516                         if(!pme->mJpegClientHandle) {
9517                             rc = pme->initJpegHandle();
9518                             if (rc != NO_ERROR) {
9519                                 LOGE("Error!! creating JPEG handle failed");
9520                                 job_status = UNKNOWN_ERROR;
9521                                 pme->sendEvtNotify(CAMERA_MSG_ERROR,
9522                                         CAMERA_ERROR_UNKNOWN, 0);
9523                                 break;
9524                             }
9525                         }
9526                         LOGH("mJpegClientHandle : %d", pme->mJpegClientHandle);
9527 
9528                         rc = postProcessor->setJpegHandle(&pme->mJpegHandle,
9529                                 &pme->mJpegMpoHandle,
9530                                 pme->mJpegClientHandle);
9531                         if (rc != 0) {
9532                             LOGE("Error!! set JPEG handle failed");
9533                             job_status = UNKNOWN_ERROR;
9534                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
9535                                     CAMERA_ERROR_UNKNOWN, 0);
9536                             break;
9537                         }
9538 
9539                         /* get max pic size for jpeg work buf calculation*/
9540                         rc = postProcessor->init(jpegEvtHandle, user_data);
9541 
9542                         if (rc != NO_ERROR) {
9543                             LOGE("cannot init postprocessor");
9544                             job_status = UNKNOWN_ERROR;
9545                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
9546                                     CAMERA_ERROR_UNKNOWN, 0);
9547                             break;
9548                         }
9549 
9550                         // update padding info from jpeg
9551                         postProcessor->getJpegPaddingReq(padding_info);
9552                         if (cam_capability_padding_info.width_padding <
9553                                 padding_info.width_padding) {
9554                             cam_capability_padding_info.width_padding =
9555                                     padding_info.width_padding;
9556                         }
9557                         if (cam_capability_padding_info.height_padding <
9558                                 padding_info.height_padding) {
9559                             cam_capability_padding_info.height_padding =
9560                                     padding_info.height_padding;
9561                         }
9562                         if (cam_capability_padding_info.plane_padding !=
9563                                 padding_info.plane_padding) {
9564                             cam_capability_padding_info.plane_padding =
9565                                     mm_stream_calc_lcm(
9566                                     cam_capability_padding_info.plane_padding,
9567                                     padding_info.plane_padding);
9568                         }
9569                         if (cam_capability_padding_info.offset_info.offset_x
9570                                 != padding_info.offset_info.offset_x) {
9571                             cam_capability_padding_info.offset_info.offset_x =
9572                                     mm_stream_calc_lcm (
9573                                     cam_capability_padding_info.offset_info.offset_x,
9574                                     padding_info.offset_info.offset_x);
9575                         }
9576                         if (cam_capability_padding_info.offset_info.offset_y
9577                                 != padding_info.offset_info.offset_y) {
9578                             cam_capability_padding_info.offset_info.offset_y =
9579                             mm_stream_calc_lcm (
9580                                     cam_capability_padding_info.offset_info.offset_y,
9581                                     padding_info.offset_info.offset_y);
9582                         }
9583                     }
9584                     break;
9585                 case CMD_DEF_PARAM_ALLOC:
9586                     {
9587                         int32_t rc = pme->mParameters.allocate();
9588                         // notify routine would not be initialized by this time.
9589                         // So, just update error job status
9590                         if (rc != NO_ERROR) {
9591                             job_status = rc;
9592                             LOGE("Param allocation failed");
9593                             break;
9594                         }
9595                     }
9596                     break;
9597                 case CMD_DEF_PARAM_INIT:
9598                     {
9599                         int32_t rc = pme->getDefJobStatus(pme->mParamAllocJob);
9600                         if (rc != NO_ERROR) {
9601                             job_status = rc;
9602                             LOGE("Param init failed");
9603                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
9604                                     CAMERA_ERROR_UNKNOWN, 0);
9605                             break;
9606                         }
9607 
9608                         uint32_t camId = pme->mCameraId;
9609                         cam_capability_t * cap = gCamCapability[camId];
9610 
9611                         if (pme->mCameraHandle == NULL) {
9612                             LOGE("Camera handle is null");
9613                             job_status = BAD_VALUE;
9614                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
9615                                     CAMERA_ERROR_UNKNOWN, 0);
9616                             break;
9617                         }
9618 
9619                         // Now PostProc need calibration data as initialization
9620                         // time for jpeg_open and calibration data is a
9621                         // get param for now, so params needs to be initialized
9622                         // before postproc init
9623                         rc = pme->mParameters.init(cap,
9624                                 pme->mCameraHandle,
9625                                 pme);
9626                         if (rc != 0) {
9627                             job_status = UNKNOWN_ERROR;
9628                             LOGE("Parameter Initialization failed");
9629                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
9630                                     CAMERA_ERROR_UNKNOWN, 0);
9631                             break;
9632                         }
9633 
9634                         // Get related cam calibration only in
9635                         // dual camera mode
9636                         if (pme->getRelatedCamSyncInfo()->sync_control ==
9637                                 CAM_SYNC_RELATED_SENSORS_ON) {
9638                             rc = pme->mParameters.getRelatedCamCalibration(
9639                                 &(pme->mJpegMetadata.otp_calibration_data));
9640                             LOGD("Dumping Calibration Data Version Id %f rc %d",
9641                                     pme->mJpegMetadata.otp_calibration_data.calibration_format_version,
9642                                     rc);
9643                             if (rc != 0) {
9644                                 job_status = UNKNOWN_ERROR;
9645                                 LOGE("getRelatedCamCalibration failed");
9646                                 pme->sendEvtNotify(CAMERA_MSG_ERROR,
9647                                         CAMERA_ERROR_UNKNOWN, 0);
9648                                 break;
9649                             }
9650                             pme->m_bRelCamCalibValid = true;
9651                         }
9652 
9653                         pme->mJpegMetadata.sensor_mount_angle =
9654                             cap->sensor_mount_angle;
9655                         pme->mJpegMetadata.default_sensor_flip = FLIP_NONE;
9656 
9657                         pme->mParameters.setMinPpMask(
9658                             cap->qcom_supported_feature_mask);
9659                         pme->mExifParams.debug_params =
9660                                 (mm_jpeg_debug_exif_params_t *)
9661                                 malloc(sizeof(mm_jpeg_debug_exif_params_t));
9662                         if (!pme->mExifParams.debug_params) {
9663                             LOGE("Out of Memory. Allocation failed for "
9664                                     "3A debug exif params");
9665                             job_status = NO_MEMORY;
9666                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
9667                                     CAMERA_ERROR_UNKNOWN, 0);
9668                             break;
9669                         }
9670                         memset(pme->mExifParams.debug_params, 0,
9671                                 sizeof(mm_jpeg_debug_exif_params_t));
9672                     }
9673                     break;
9674                 case CMD_DEF_GENERIC:
9675                     {
9676                         BackgroundTask *bgTask = dw->args.genericArgs;
9677                         job_status = bgTask->bgFunction(bgTask->bgArgs);
9678                     }
9679                     break;
9680                 default:
9681                     LOGE("Incorrect command : %d", dw->cmd);
9682                 }
9683 
9684                 pme->dequeueDeferredWork(dw, job_status);
9685             }
9686             break;
9687         case CAMERA_CMD_TYPE_EXIT:
9688             running = 0;
9689             break;
9690         default:
9691             break;
9692         }
9693     } while (running);
9694 
9695     return NULL;
9696 }
9697 
9698 /*===========================================================================
9699  * FUNCTION   : queueDeferredWork
9700  *
9701  * DESCRIPTION: function which queues deferred tasks
9702  *
9703  * PARAMETERS :
9704  *   @cmd     : deferred task
9705  *   @args    : deferred task arguments
9706  *
9707  * RETURN     : job id of deferred job
9708  *            : 0 in case of error
9709  *==========================================================================*/
queueDeferredWork(DeferredWorkCmd cmd,DeferWorkArgs args)9710 uint32_t QCamera2HardwareInterface::queueDeferredWork(DeferredWorkCmd cmd,
9711                                                       DeferWorkArgs args)
9712 {
9713     Mutex::Autolock l(mDefLock);
9714     for (int32_t i = 0; i < MAX_ONGOING_JOBS; ++i) {
9715         if (mDefOngoingJobs[i].mDefJobId == 0) {
9716             DefWork *dw = new DefWork(cmd, sNextJobId, args);
9717             if (!dw) {
9718                 LOGE("out of memory.");
9719                 return 0;
9720             }
9721             if (mCmdQueue.enqueue(dw)) {
9722                 mDefOngoingJobs[i].mDefJobId = sNextJobId++;
9723                 mDefOngoingJobs[i].mDefJobStatus = 0;
9724                 if (sNextJobId == 0) { // handle overflow
9725                     sNextJobId = 1;
9726                 }
9727                 mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB,
9728                         FALSE,
9729                         FALSE);
9730                 return mDefOngoingJobs[i].mDefJobId;
9731             } else {
9732                 LOGD("Command queue not active! cmd = %d", cmd);
9733                 delete dw;
9734                 return 0;
9735             }
9736         }
9737     }
9738     return 0;
9739 }
9740 
9741 /*===========================================================================
9742  * FUNCTION   : initJpegHandle
9743  *
9744  * DESCRIPTION: Opens JPEG client and gets a handle.
9745  *                     Sends Dual cam calibration info if present
9746  *
9747  * RETURN     : int32_t type of status
9748  *              NO_ERROR  -- success
9749  *              none-zero failure code
9750  *==========================================================================*/
initJpegHandle()9751 int32_t QCamera2HardwareInterface::initJpegHandle() {
9752     // Check if JPEG client handle is present
9753     LOGH("E");
9754     if(!mJpegClientHandle) {
9755         mm_dimension max_size = {0, 0};
9756         cam_dimension_t size;
9757 
9758         mParameters.getMaxPicSize(size);
9759         max_size.w = size.width;
9760         max_size.h = size.height;
9761 
9762         if (getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
9763             if (m_bRelCamCalibValid) {
9764                 mJpegClientHandle = jpeg_open(&mJpegHandle, &mJpegMpoHandle,
9765                         max_size, &mJpegMetadata);
9766             } else {
9767                 mJpegClientHandle =  jpeg_open(&mJpegHandle, &mJpegMpoHandle,
9768                         max_size, NULL);
9769             }
9770         } else {
9771             mJpegClientHandle = jpeg_open(&mJpegHandle, NULL, max_size, NULL);
9772         }
9773         if (!mJpegClientHandle) {
9774             LOGE("Error !! jpeg_open failed!! ");
9775             return UNKNOWN_ERROR;
9776         }
9777         // Set JPEG initialized as true to signify that this camera
9778         // has initialized the handle
9779         mJpegHandleOwner = true;
9780     }
9781     LOGH("X mJpegHandleOwner: %d, mJpegClientHandle: %d camera id: %d",
9782              mJpegHandleOwner, mJpegClientHandle, mCameraId);
9783     return NO_ERROR;
9784 }
9785 
9786 /*===========================================================================
9787  * FUNCTION   : deinitJpegHandle
9788  *
9789  * DESCRIPTION: Closes JPEG client using handle
9790  *
9791  * RETURN     : int32_t type of status
9792  *              NO_ERROR  -- success
9793  *              none-zero failure code
9794  *==========================================================================*/
deinitJpegHandle()9795 int32_t QCamera2HardwareInterface::deinitJpegHandle() {
9796     int32_t rc = NO_ERROR;
9797     LOGH("E");
9798     // Check if JPEG client handle is present and inited by this camera
9799     if(mJpegHandleOwner && mJpegClientHandle) {
9800         rc = mJpegHandle.close(mJpegClientHandle);
9801         if (rc != NO_ERROR) {
9802             LOGE("Error!! Closing mJpegClientHandle: %d failed",
9803                      mJpegClientHandle);
9804         }
9805         memset(&mJpegHandle, 0, sizeof(mJpegHandle));
9806         memset(&mJpegMpoHandle, 0, sizeof(mJpegMpoHandle));
9807         mJpegHandleOwner = false;
9808     }
9809     mJpegClientHandle = 0;
9810     LOGH("X rc = %d", rc);
9811     return rc;
9812 }
9813 
9814 /*===========================================================================
9815  * FUNCTION   : setJpegHandleInfo
9816  *
9817  * DESCRIPTION: sets JPEG client handle info
9818  *
9819  * PARAMETERS:
9820  *                  @ops                    : JPEG ops
9821  *                  @mpo_ops             : Jpeg MPO ops
9822  *                  @pJpegClientHandle : o/p Jpeg Client Handle
9823  *
9824  * RETURN     : int32_t type of status
9825  *              NO_ERROR  -- success
9826  *              none-zero failure code
9827  *==========================================================================*/
setJpegHandleInfo(mm_jpeg_ops_t * ops,mm_jpeg_mpo_ops_t * mpo_ops,uint32_t pJpegClientHandle)9828 int32_t QCamera2HardwareInterface::setJpegHandleInfo(mm_jpeg_ops_t *ops,
9829         mm_jpeg_mpo_ops_t *mpo_ops, uint32_t pJpegClientHandle) {
9830 
9831     if (pJpegClientHandle && ops && mpo_ops) {
9832         LOGH("Setting JPEG client handle %d",
9833                 pJpegClientHandle);
9834         memcpy(&mJpegHandle, ops, sizeof(mm_jpeg_ops_t));
9835         memcpy(&mJpegMpoHandle, mpo_ops, sizeof(mm_jpeg_mpo_ops_t));
9836         mJpegClientHandle = pJpegClientHandle;
9837         return NO_ERROR;
9838     }
9839     else {
9840         LOGE("Error!! No Handle found: %d",
9841                 pJpegClientHandle);
9842         return BAD_VALUE;
9843     }
9844 }
9845 
9846 /*===========================================================================
9847  * FUNCTION   : getJpegHandleInfo
9848  *
9849  * DESCRIPTION: gets JPEG client handle info
9850  *
9851  * PARAMETERS:
9852  *                  @ops                    : JPEG ops
9853  *                  @mpo_ops             : Jpeg MPO ops
9854  *                  @pJpegClientHandle : o/p Jpeg Client Handle
9855  *
9856  * RETURN     : int32_t type of status
9857  *              NO_ERROR  -- success
9858  *              none-zero failure code
9859  *==========================================================================*/
getJpegHandleInfo(mm_jpeg_ops_t * ops,mm_jpeg_mpo_ops_t * mpo_ops,uint32_t * pJpegClientHandle)9860 int32_t QCamera2HardwareInterface::getJpegHandleInfo(mm_jpeg_ops_t *ops,
9861         mm_jpeg_mpo_ops_t *mpo_ops, uint32_t *pJpegClientHandle) {
9862 
9863     if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
9864         LOGE("Init PProc Deferred work failed");
9865         return UNKNOWN_ERROR;
9866     }
9867     // Copy JPEG ops if present
9868     if (ops && mpo_ops && pJpegClientHandle) {
9869         memcpy(ops, &mJpegHandle, sizeof(mm_jpeg_ops_t));
9870         memcpy(mpo_ops, &mJpegMpoHandle, sizeof(mm_jpeg_mpo_ops_t));
9871         *pJpegClientHandle = mJpegClientHandle;
9872         LOGH("Getting JPEG client handle %d",
9873                 pJpegClientHandle);
9874         return NO_ERROR;
9875     } else {
9876         return BAD_VALUE;
9877     }
9878 }
9879 
9880 /*===========================================================================
9881  * FUNCTION   : dequeueDeferredWork
9882  *
9883  * DESCRIPTION: function which dequeues deferred tasks
9884  *
9885  * PARAMETERS :
9886  *   @dw      : deferred work
9887  *   @jobStatus: deferred task job status
9888  *
9889  * RETURN     : int32_t type of status
9890  *              NO_ERROR  -- success
9891  *              none-zero failure code
9892  *==========================================================================*/
dequeueDeferredWork(DefWork * dw,int32_t jobStatus)9893 uint32_t QCamera2HardwareInterface::dequeueDeferredWork(DefWork* dw, int32_t jobStatus)
9894 {
9895     Mutex::Autolock l(mDefLock);
9896     for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) {
9897         if (mDefOngoingJobs[i].mDefJobId == dw->id) {
9898             if (jobStatus != NO_ERROR) {
9899                 mDefOngoingJobs[i].mDefJobStatus = jobStatus;
9900                 LOGH("updating job status %d for id %d",
9901                          jobStatus, dw->id);
9902             } else {
9903                 mDefOngoingJobs[i].mDefJobId = 0;
9904                 mDefOngoingJobs[i].mDefJobStatus = 0;
9905             }
9906             delete dw;
9907             mDefCond.broadcast();
9908             return NO_ERROR;
9909         }
9910     }
9911 
9912     return UNKNOWN_ERROR;
9913 }
9914 
9915 /*===========================================================================
9916  * FUNCTION   : getDefJobStatus
9917  *
9918  * DESCRIPTION: Gets if a deferred task is success/fail
9919  *
9920  * PARAMETERS :
9921  *   @job_id  : deferred task id
9922  *
9923  * RETURN     : NO_ERROR if the job success, otherwise false
9924  *
9925  * PRECONDITION : mDefLock is held by current thread
9926  *==========================================================================*/
getDefJobStatus(uint32_t & job_id)9927 int32_t QCamera2HardwareInterface::getDefJobStatus(uint32_t &job_id)
9928 {
9929     for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) {
9930         if (mDefOngoingJobs[i].mDefJobId == job_id) {
9931             if ( NO_ERROR != mDefOngoingJobs[i].mDefJobStatus ) {
9932                 LOGE("job_id (%d) was failed", job_id);
9933                 return mDefOngoingJobs[i].mDefJobStatus;
9934             }
9935             else
9936                 return NO_ERROR;
9937         }
9938     }
9939     return NO_ERROR;
9940 }
9941 
9942 
9943 /*===========================================================================
9944  * FUNCTION   : checkDeferredWork
9945  *
9946  * DESCRIPTION: checks if a deferred task is in progress
9947  *
9948  * PARAMETERS :
9949  *   @job_id  : deferred task id
9950  *
9951  * RETURN     : true if the task exists, otherwise false
9952  *
9953  * PRECONDITION : mDefLock is held by current thread
9954  *==========================================================================*/
checkDeferredWork(uint32_t & job_id)9955 bool QCamera2HardwareInterface::checkDeferredWork(uint32_t &job_id)
9956 {
9957     for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) {
9958         if (mDefOngoingJobs[i].mDefJobId == job_id) {
9959             return (NO_ERROR == mDefOngoingJobs[i].mDefJobStatus);
9960         }
9961     }
9962     return false;
9963 }
9964 
9965 /*===========================================================================
9966  * FUNCTION   : waitDeferredWork
9967  *
9968  * DESCRIPTION: waits for a deferred task to finish
9969  *
9970  * PARAMETERS :
9971  *   @job_id  : deferred task id
9972  *
9973  * RETURN     : int32_t type of status
9974  *              NO_ERROR  -- success
9975  *              none-zero failure code
9976  *==========================================================================*/
waitDeferredWork(uint32_t & job_id)9977 int32_t QCamera2HardwareInterface::waitDeferredWork(uint32_t &job_id)
9978 {
9979     Mutex::Autolock l(mDefLock);
9980 
9981     if (job_id == 0) {
9982         LOGD("Invalid job id %d", job_id);
9983         return NO_ERROR;
9984     }
9985 
9986     while (checkDeferredWork(job_id) == true ) {
9987         mDefCond.waitRelative(mDefLock, CAMERA_DEFERRED_THREAD_TIMEOUT);
9988     }
9989     return getDefJobStatus(job_id);
9990 }
9991 
9992 /*===========================================================================
9993  * FUNCTION   : scheduleBackgroundTask
9994  *
9995  * DESCRIPTION: Run a requested task in the deferred thread
9996  *
9997  * PARAMETERS :
9998  *   @bgTask  : Task to perform in the background
9999  *
10000  * RETURN     : job id of deferred job
10001  *            : 0 in case of error
10002  *==========================================================================*/
scheduleBackgroundTask(BackgroundTask * bgTask)10003 uint32_t QCamera2HardwareInterface::scheduleBackgroundTask(BackgroundTask* bgTask)
10004 {
10005     DeferWorkArgs args;
10006     memset(&args, 0, sizeof(DeferWorkArgs));
10007     args.genericArgs = bgTask;
10008 
10009     return queueDeferredWork(CMD_DEF_GENERIC, args);
10010 }
10011 
10012 /*===========================================================================
10013  * FUNCTION   : waitForBackgroundTask
10014  *
10015  * DESCRIPTION: Wait for a background task to complete
10016  *
10017  * PARAMETERS :
10018  *   @taskId  : Task id to wait for
10019  *
10020  * RETURN     : int32_t type of status
10021  *              NO_ERROR  -- success
10022  *              none-zero failure code
10023  *==========================================================================*/
waitForBackgroundTask(uint32_t & taskId)10024 int32_t QCamera2HardwareInterface::waitForBackgroundTask(uint32_t& taskId)
10025 {
10026     return waitDeferredWork(taskId);
10027 }
10028 
10029 /*===========================================================================
10030  * FUNCTION   : needDeferedAllocation
10031  *
10032  * DESCRIPTION: Function to decide background task for streams
10033  *
10034  * PARAMETERS :
10035  *   @stream_type  : stream type
10036  *
10037  * RETURN     : true - if background task is needed
10038  *              false -  if background task is NOT needed
10039  *==========================================================================*/
needDeferred(cam_stream_type_t stream_type)10040 bool QCamera2HardwareInterface::needDeferred(cam_stream_type_t stream_type)
10041 {
10042     if ((stream_type == CAM_STREAM_TYPE_PREVIEW && mPreviewWindow == NULL)
10043             || (stream_type == CAM_STREAM_TYPE_ANALYSIS)) {
10044         return FALSE;
10045     }
10046 
10047     if ((stream_type == CAM_STREAM_TYPE_RAW)
10048             && (mParameters.getofflineRAW())) {
10049         return FALSE;
10050     }
10051 
10052     if ((stream_type == CAM_STREAM_TYPE_SNAPSHOT)
10053             && (!mParameters.getRecordingHintValue())){
10054         return TRUE;
10055     }
10056 
10057     if ((stream_type == CAM_STREAM_TYPE_PREVIEW)
10058             || (stream_type == CAM_STREAM_TYPE_METADATA)
10059             || (stream_type == CAM_STREAM_TYPE_RAW)
10060             || (stream_type == CAM_STREAM_TYPE_POSTVIEW)) {
10061         return TRUE;
10062     }
10063 
10064     if (stream_type == CAM_STREAM_TYPE_VIDEO) {
10065         return FALSE;
10066     }
10067     return FALSE;
10068 }
10069 
10070 /*===========================================================================
10071  * FUNCTION   : isRegularCapture
10072  *
10073  * DESCRIPTION: Check configuration for regular catpure
10074  *
10075  * PARAMETERS :
10076  *
10077  * RETURN     : true - regular capture
10078  *              false - other type of capture
10079  *==========================================================================*/
isRegularCapture()10080 bool QCamera2HardwareInterface::isRegularCapture()
10081 {
10082     bool ret = false;
10083 
10084     if (numOfSnapshotsExpected() == 1 &&
10085         !isLongshotEnabled() &&
10086         !mParameters.isHDREnabled() &&
10087         !mParameters.getRecordingHintValue() &&
10088         !isZSLMode() && !mParameters.getofflineRAW()) {
10089             ret = true;
10090     }
10091     return ret;
10092 }
10093 
10094 /*===========================================================================
10095  * FUNCTION   : getLogLevel
10096  *
10097  * DESCRIPTION: Reads the log level property into a variable
10098  *
10099  * PARAMETERS :
10100  *   None
10101  *
10102  * RETURN     :
10103  *   None
10104  *==========================================================================*/
getLogLevel()10105 void QCamera2HardwareInterface::getLogLevel()
10106 {
10107     char prop[PROPERTY_VALUE_MAX];
10108 
10109     property_get("persist.camera.kpi.debug", prop, "1");
10110     gKpiDebugLevel = atoi(prop);
10111     return;
10112 }
10113 
10114 /*===========================================================================
10115  * FUNCTION   : getSensorType
10116  *
10117  * DESCRIPTION: Returns the type of sensor being used whether YUV or Bayer
10118  *
10119  * PARAMETERS :
10120  *   None
10121  *
10122  * RETURN     : Type of sensor - bayer or YUV
10123  *
10124  *==========================================================================*/
getSensorType()10125 cam_sensor_t QCamera2HardwareInterface::getSensorType()
10126 {
10127     return gCamCapability[mCameraId]->sensor_type.sens_type;
10128 }
10129 
10130 /*===========================================================================
10131  * FUNCTION   : startRAWChannel
10132  *
10133  * DESCRIPTION: start RAW Channel
10134  *
10135  * PARAMETERS :
10136  *   @pChannel  : Src channel to link this RAW channel.
10137  *
10138  * RETURN     : int32_t type of status
10139  *              NO_ERROR  -- success
10140  *              none-zero failure code
10141  *==========================================================================*/
startRAWChannel(QCameraChannel * pMetaChannel)10142 int32_t QCamera2HardwareInterface::startRAWChannel(QCameraChannel *pMetaChannel)
10143 {
10144     int32_t rc = NO_ERROR;
10145     QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_RAW];
10146     if ((NULL != pChannel) && (mParameters.getofflineRAW())) {
10147         // Find and try to link a metadata stream from preview channel
10148         QCameraStream *pMetaStream = NULL;
10149 
10150         if (pMetaChannel != NULL) {
10151             uint32_t streamNum = pMetaChannel->getNumOfStreams();
10152             QCameraStream *pStream = NULL;
10153             for (uint32_t i = 0 ; i < streamNum ; i++ ) {
10154                 pStream = pMetaChannel->getStreamByIndex(i);
10155                 if ((NULL != pStream) &&
10156                         (CAM_STREAM_TYPE_METADATA == pStream->getMyType())) {
10157                     pMetaStream = pStream;
10158                     break;
10159                 }
10160             }
10161 
10162             if (NULL != pMetaStream) {
10163                 rc = pChannel->linkStream(pMetaChannel, pMetaStream);
10164                 if (NO_ERROR != rc) {
10165                     LOGE("Metadata stream link failed %d", rc);
10166                 }
10167             }
10168         }
10169         rc = pChannel->start();
10170     }
10171     return rc;
10172 }
10173 
10174 /*===========================================================================
10175  * FUNCTION   : startRecording
10176  *
10177  * DESCRIPTION: start recording impl
10178  *
10179  * PARAMETERS : none
10180  *
10181  * RETURN     : int32_t type of status
10182  *              NO_ERROR  -- success
10183  *              none-zero failure code
10184  *==========================================================================*/
stopRAWChannel()10185 int32_t QCamera2HardwareInterface::stopRAWChannel()
10186 {
10187     int32_t rc = NO_ERROR;
10188     rc = stopChannel(QCAMERA_CH_TYPE_RAW);
10189     return rc;
10190 }
10191 
10192 /*===========================================================================
10193  * FUNCTION   : isLowPowerMode
10194  *
10195  * DESCRIPTION: Returns TRUE if low power mode settings are to be applied for video recording
10196  *
10197  * PARAMETERS :
10198  *   None
10199  *
10200  * RETURN     : TRUE/FALSE
10201  *
10202  *==========================================================================*/
isLowPowerMode()10203 bool QCamera2HardwareInterface::isLowPowerMode()
10204 {
10205     cam_dimension_t dim;
10206     mParameters.getStreamDimension(CAM_STREAM_TYPE_VIDEO, dim);
10207 
10208     char prop[PROPERTY_VALUE_MAX];
10209     property_get("camera.lowpower.record.enable", prop, "0");
10210     int enable = atoi(prop);
10211 
10212     //Enable low power mode if :
10213     //1. Video resolution is 2k (2048x1080) or above and
10214     //2. camera.lowpower.record.enable is set
10215 
10216     bool isLowpower = mParameters.getRecordingHintValue() && enable
10217             && ((dim.width * dim.height) >= (2048 * 1080));
10218     return isLowpower;
10219 }
10220 
10221 }; // namespace qcamera
10222