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