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