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