1 /* Copyright (c) 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 "QCameraCommon"
31
32 #include <cutils/properties.h>
33
34 // System dependencies
35 #include <utils/Errors.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <utils/Log.h>
39 #include <math.h>
40
41
42 // Camera dependencies
43 #include "QCameraCommon.h"
44
45 extern "C" {
46 #include "mm_camera_dbg.h"
47 }
48
49 using namespace android;
50
51 namespace qcamera {
52
53 #ifndef TRUE
54 #define TRUE 1
55 #endif
56
57 #ifndef FALSE
58 #define FALSE 0
59 #endif
60
61 #define ASPECT_RATIO_TOLERANCE 0.01
62
63 /*===========================================================================
64 * FUNCTION : QCameraCommon
65 *
66 * DESCRIPTION: default constructor of QCameraCommon
67 *
68 * PARAMETERS : None
69 *
70 * RETURN : None
71 *==========================================================================*/
QCameraCommon()72 QCameraCommon::QCameraCommon() :
73 m_pCapability(NULL)
74 {
75 }
76
77 /*===========================================================================
78 * FUNCTION : ~QCameraCommon
79 *
80 * DESCRIPTION: destructor of QCameraCommon
81 *
82 * PARAMETERS : None
83 *
84 * RETURN : None
85 *==========================================================================*/
~QCameraCommon()86 QCameraCommon::~QCameraCommon()
87 {
88 }
89
90 /*===========================================================================
91 * FUNCTION : init
92 *
93 * DESCRIPTION: Init function for QCameraCommon
94 *
95 * PARAMETERS :
96 * @pCapability : Capabilities
97 *
98 * RETURN : int32_t type of status
99 * NO_ERROR -- success
100 * none-zero failure code
101 *==========================================================================*/
init(cam_capability_t * pCapability)102 int32_t QCameraCommon::init(cam_capability_t *pCapability)
103 {
104 m_pCapability = pCapability;
105
106 return NO_ERROR;
107 }
108
109 /*===========================================================================
110 * FUNCTION : calculateLCM
111 *
112 * DESCRIPTION: Get the LCM of 2 numbers
113 *
114 * PARAMETERS :
115 * @num1 : First number
116 * @num2 : second number
117 *
118 * RETURN : int32_t type (LCM)
119 *
120 *==========================================================================*/
calculateLCM(int32_t num1,int32_t num2)121 uint32_t QCameraCommon::calculateLCM(int32_t num1, int32_t num2)
122 {
123 uint32_t lcm = 0;
124 uint32_t temp = 0;
125
126 if ((num1 < 1) && (num2 < 1)) {
127 return 0;
128 } else if (num1 < 1) {
129 return num2;
130 } else if (num2 < 1) {
131 return num1;
132 }
133
134 if (num1 > num2) {
135 lcm = num1;
136 } else {
137 lcm = num2;
138 }
139 temp = lcm;
140
141 while (1) {
142 if (((lcm % num1) == 0) && ((lcm % num2) == 0)) {
143 break;
144 }
145 lcm += temp;
146 }
147 return lcm;
148 }
149
150 /*===========================================================================
151 * FUNCTION : getAnalysisInfo
152 *
153 * DESCRIPTION: Get the Analysis information based on
154 * current mode and feature mask
155 *
156 * PARAMETERS :
157 * @fdVideoEnabled : Whether fdVideo enabled currently
158 * @hal3 : Whether hal3 or hal1
159 * @featureMask : Feature mask
160 * @pAnalysis_info : Analysis info to be filled
161 *
162 * RETURN : int32_t type of status
163 * NO_ERROR -- success
164 * none-zero failure code
165 *==========================================================================*/
getAnalysisInfo(bool fdVideoEnabled,cam_feature_mask_t featureMask,cam_analysis_info_t * pAnalysisInfo)166 int32_t QCameraCommon::getAnalysisInfo(
167 bool fdVideoEnabled,
168 cam_feature_mask_t featureMask,
169 cam_analysis_info_t *pAnalysisInfo)
170 {
171 if (!pAnalysisInfo) {
172 return BAD_VALUE;
173 }
174
175 pAnalysisInfo->valid = 0;
176
177 if ((fdVideoEnabled == TRUE) &&
178 (m_pCapability->analysis_info[CAM_ANALYSIS_INFO_FD_VIDEO].hw_analysis_supported) &&
179 (m_pCapability->analysis_info[CAM_ANALYSIS_INFO_FD_VIDEO].valid)) {
180 *pAnalysisInfo =
181 m_pCapability->analysis_info[CAM_ANALYSIS_INFO_FD_VIDEO];
182 } else if (m_pCapability->analysis_info[CAM_ANALYSIS_INFO_FD_STILL].valid) {
183 *pAnalysisInfo =
184 m_pCapability->analysis_info[CAM_ANALYSIS_INFO_FD_STILL];
185 }
186
187 if ((featureMask & CAM_QCOM_FEATURE_PAAF) &&
188 (m_pCapability->analysis_info[CAM_ANALYSIS_INFO_PAAF].valid)) {
189 cam_analysis_info_t *pPaafInfo =
190 &m_pCapability->analysis_info[CAM_ANALYSIS_INFO_PAAF];
191
192 if (!pAnalysisInfo->valid) {
193 *pAnalysisInfo = *pPaafInfo;
194 } else {
195 pAnalysisInfo->analysis_max_res.width =
196 MAX(pAnalysisInfo->analysis_max_res.width,
197 pPaafInfo->analysis_max_res.width);
198 pAnalysisInfo->analysis_max_res.height =
199 MAX(pAnalysisInfo->analysis_max_res.height,
200 pPaafInfo->analysis_max_res.height);
201 pAnalysisInfo->analysis_recommended_res.width =
202 MAX(pAnalysisInfo->analysis_recommended_res.width,
203 pPaafInfo->analysis_recommended_res.width);
204 pAnalysisInfo->analysis_recommended_res.height =
205 MAX(pAnalysisInfo->analysis_recommended_res.height,
206 pPaafInfo->analysis_recommended_res.height);
207 pAnalysisInfo->analysis_padding_info.height_padding =
208 calculateLCM(pAnalysisInfo->analysis_padding_info.height_padding,
209 pPaafInfo->analysis_padding_info.height_padding);
210 pAnalysisInfo->analysis_padding_info.width_padding =
211 calculateLCM(pAnalysisInfo->analysis_padding_info.width_padding,
212 pPaafInfo->analysis_padding_info.width_padding);
213 pAnalysisInfo->analysis_padding_info.plane_padding =
214 calculateLCM(pAnalysisInfo->analysis_padding_info.plane_padding,
215 pPaafInfo->analysis_padding_info.plane_padding);
216 pAnalysisInfo->analysis_padding_info.min_stride =
217 MAX(pAnalysisInfo->analysis_padding_info.min_stride,
218 pPaafInfo->analysis_padding_info.min_stride);
219 pAnalysisInfo->analysis_padding_info.min_stride =
220 ALIGN(pAnalysisInfo->analysis_padding_info.min_stride,
221 pAnalysisInfo->analysis_padding_info.width_padding);
222
223 pAnalysisInfo->analysis_padding_info.min_scanline =
224 MAX(pAnalysisInfo->analysis_padding_info.min_scanline,
225 pPaafInfo->analysis_padding_info.min_scanline);
226 pAnalysisInfo->analysis_padding_info.min_scanline =
227 ALIGN(pAnalysisInfo->analysis_padding_info.min_scanline,
228 pAnalysisInfo->analysis_padding_info.height_padding);
229
230 pAnalysisInfo->hw_analysis_supported |=
231 pPaafInfo->hw_analysis_supported;
232 }
233 }
234 return pAnalysisInfo->valid ? NO_ERROR : BAD_VALUE;
235 }
236
237 /*===========================================================================
238 * FUNCTION : getMatchingDimension
239 *
240 * DESCRIPTION: Get dimension closest to the current, but with matching aspect ratio
241 *
242 * PARAMETERS :
243 * @exp_dim : The dimension corresponding to desired aspect ratio
244 * @cur_dim : The dimension which has to be modified
245 *
246 * RETURN : cam_dimension_t new dimensions as per desired aspect ratio
247 *==========================================================================*/
getMatchingDimension(cam_dimension_t exp_dim,cam_dimension_t cur_dim)248 cam_dimension_t QCameraCommon::getMatchingDimension(
249 cam_dimension_t exp_dim,
250 cam_dimension_t cur_dim)
251 {
252 cam_dimension_t expected_dim = cur_dim;
253 if ((exp_dim.width != 0) && (exp_dim.height != 0)) {
254 double cur_ratio, expected_ratio;
255
256 cur_ratio = (double)cur_dim.width / (double)cur_dim.height;
257 expected_ratio = (double)exp_dim.width / (double)exp_dim.height;
258 if (fabs(cur_ratio - expected_ratio) > ASPECT_RATIO_TOLERANCE) {
259 if (cur_ratio < expected_ratio) {
260 expected_dim.height = (int32_t)((double)cur_dim.width / expected_ratio);
261 } else {
262 expected_dim.width = (int32_t)((double)cur_dim.height * expected_ratio);
263 }
264 expected_dim.width &= ~0x1;
265 expected_dim.height &= ~0x1;
266 }
267 LOGD("exp ratio: %f, cur ratio: %f, new dim: %d x %d",
268 expected_ratio, cur_ratio, exp_dim.width, exp_dim.height);
269 }
270 return expected_dim;
271 }
272
273
274
275 /*===========================================================================
276 * FUNCTION : isVideoUBWCEnabled
277 *
278 * DESCRIPTION: Function to get UBWC hardware support for video.
279 *
280 * PARAMETERS : None
281 *
282 * RETURN : TRUE -- UBWC format supported
283 * FALSE -- UBWC is not supported.
284 *==========================================================================*/
285
isVideoUBWCEnabled()286 bool QCameraCommon::isVideoUBWCEnabled()
287 {
288 #ifdef UBWC_PRESENT
289 char prop[PROPERTY_VALUE_MAX];
290 int pFormat;
291 memset(prop, 0, sizeof(prop));
292 /* Checking the property set by video
293 * to disable/enable UBWC */
294 property_get("video.disable.ubwc", prop, "0");
295 pFormat = atoi(prop);
296 if (pFormat == 0) {
297 return TRUE;
298 }
299 return FALSE;
300 #else
301 return FALSE;
302 #endif
303 }
304
305 }; // namespace qcamera
306