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 *==========================================================================*/ 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 *==========================================================================*/ 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 *==========================================================================*/ 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 *==========================================================================*/ 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 *==========================================================================*/ 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 *==========================================================================*/ 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 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