1 /* 2 * Copyright (C) Texas Instruments - http://www.ti.com/ 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /** 18 * @file V4LCapabilities.cpp 19 * 20 * This file implements the V4L Capabilities feature. 21 * 22 */ 23 24 #include "CameraHal.h" 25 #include "V4LCameraAdapter.h" 26 #include "ErrorUtils.h" 27 #include "TICameraParameters.h" 28 29 namespace Ti { 30 namespace Camera { 31 32 /************************************ 33 * global constants and variables 34 *************************************/ 35 36 #define ARRAY_SIZE(array) (sizeof((array)) / sizeof((array)[0])) 37 #define MAX_RES_STRING_LENGTH 10 38 #define DEFAULT_WIDTH 640 39 #define DEFAULT_HEIGHT 480 40 41 static const char PARAM_SEP[] = ","; 42 43 //Camera defaults 44 const char V4LCameraAdapter::DEFAULT_PICTURE_FORMAT[] = "jpeg"; 45 const char V4LCameraAdapter::DEFAULT_PICTURE_SIZE[] = "640x480"; 46 const char V4LCameraAdapter::DEFAULT_PREVIEW_FORMAT[] = "yuv422i-yuyv"; 47 const char V4LCameraAdapter::DEFAULT_PREVIEW_SIZE[] = "640x480"; 48 const char V4LCameraAdapter::DEFAULT_NUM_PREV_BUFS[] = "6"; 49 const char V4LCameraAdapter::DEFAULT_FRAMERATE[] = "30"; 50 const char V4LCameraAdapter::DEFAULT_FOCUS_MODE[] = "infinity"; 51 const char * V4LCameraAdapter::DEFAULT_VSTAB = android::CameraParameters::FALSE; 52 const char * V4LCameraAdapter::DEFAULT_VNF = android::CameraParameters::FALSE; 53 54 55 const CapPixelformat V4LCameraAdapter::mPixelformats [] = { 56 { V4L2_PIX_FMT_YUYV, android::CameraParameters::PIXEL_FORMAT_YUV422I }, 57 { V4L2_PIX_FMT_JPEG, android::CameraParameters::PIXEL_FORMAT_JPEG }, 58 }; 59 60 /***************************************** 61 * internal static function declarations 62 *****************************************/ 63 64 /**** Utility functions to help translate V4L Caps to Parameter ****/ 65 66 status_t V4LCameraAdapter::insertDefaults(CameraProperties::Properties* params, V4L_TI_CAPTYPE &caps) 67 { 68 status_t ret = NO_ERROR; 69 LOG_FUNCTION_NAME; 70 71 params->set(CameraProperties::PREVIEW_FORMAT, DEFAULT_PREVIEW_FORMAT); 72 73 params->set(CameraProperties::PICTURE_FORMAT, DEFAULT_PICTURE_FORMAT); 74 params->set(CameraProperties::PICTURE_SIZE, DEFAULT_PICTURE_SIZE); 75 params->set(CameraProperties::PREVIEW_SIZE, DEFAULT_PREVIEW_SIZE); 76 params->set(CameraProperties::PREVIEW_FRAME_RATE, DEFAULT_FRAMERATE); 77 params->set(CameraProperties::REQUIRED_PREVIEW_BUFS, DEFAULT_NUM_PREV_BUFS); 78 params->set(CameraProperties::FOCUS_MODE, DEFAULT_FOCUS_MODE); 79 80 params->set(CameraProperties::CAMERA_NAME, "USBCAMERA"); 81 params->set(CameraProperties::JPEG_THUMBNAIL_SIZE, "320x240"); 82 params->set(CameraProperties::JPEG_QUALITY, "90"); 83 params->set(CameraProperties::JPEG_THUMBNAIL_QUALITY, "50"); 84 params->set(CameraProperties::FRAMERATE_RANGE_SUPPORTED, "(30000,30000)"); 85 params->set(CameraProperties::FRAMERATE_RANGE, "30000,30000"); 86 params->set(CameraProperties::S3D_PRV_FRAME_LAYOUT, "none"); 87 params->set(CameraProperties::SUPPORTED_EXPOSURE_MODES, "auto"); 88 params->set(CameraProperties::SUPPORTED_ISO_VALUES, "auto"); 89 params->set(CameraProperties::SUPPORTED_ANTIBANDING, "auto"); 90 params->set(CameraProperties::SUPPORTED_EFFECTS, "none"); 91 params->set(CameraProperties::SUPPORTED_IPP_MODES, "ldc-nsf"); 92 params->set(CameraProperties::FACING_INDEX, TICameraParameters::FACING_FRONT); 93 params->set(CameraProperties::ORIENTATION_INDEX, 0); 94 params->set(CameraProperties::SENSOR_ORIENTATION, "0"); 95 params->set(CameraProperties::VSTAB, DEFAULT_VSTAB); 96 params->set(CameraProperties::VNF, DEFAULT_VNF); 97 98 99 LOG_FUNCTION_NAME_EXIT; 100 101 return ret; 102 } 103 104 status_t V4LCameraAdapter::insertPreviewFormats(CameraProperties::Properties* params, V4L_TI_CAPTYPE &caps) { 105 106 char supported[MAX_PROP_VALUE_LENGTH]; 107 108 memset(supported, '\0', MAX_PROP_VALUE_LENGTH); 109 for (int i = 0; i < caps.ulPreviewFormatCount; i++) { 110 for (unsigned int j = 0; j < ARRAY_SIZE(mPixelformats); j++) { 111 if(caps.ePreviewFormats[i] == mPixelformats[j].pixelformat ) { 112 strncat (supported, mPixelformats[j].param, MAX_PROP_VALUE_LENGTH-1 ); 113 strncat (supported, PARAM_SEP, 1 ); 114 } 115 } 116 } 117 strncat(supported, android::CameraParameters::PIXEL_FORMAT_YUV420P, MAX_PROP_VALUE_LENGTH - 1); 118 params->set(CameraProperties::SUPPORTED_PREVIEW_FORMATS, supported); 119 return NO_ERROR; 120 } 121 122 status_t V4LCameraAdapter::insertPreviewSizes(CameraProperties::Properties* params, V4L_TI_CAPTYPE &caps) { 123 124 char supported[MAX_PROP_VALUE_LENGTH]; 125 126 memset(supported, '\0', MAX_PROP_VALUE_LENGTH); 127 for (int i = 0; i < caps.ulPreviewResCount; i++) { 128 if (supported[0] != '\0') { 129 strncat(supported, PARAM_SEP, 1); 130 } 131 strncat (supported, caps.tPreviewRes[i].param, MAX_PROP_VALUE_LENGTH-1 ); 132 } 133 134 params->set(CameraProperties::SUPPORTED_PREVIEW_SIZES, supported); 135 params->set(CameraProperties::SUPPORTED_PREVIEW_SUBSAMPLED_SIZES, supported); 136 return NO_ERROR; 137 } 138 139 status_t V4LCameraAdapter::insertImageSizes(CameraProperties::Properties* params, V4L_TI_CAPTYPE &caps) { 140 141 char supported[MAX_PROP_VALUE_LENGTH]; 142 143 memset(supported, '\0', MAX_PROP_VALUE_LENGTH); 144 for (int i = 0; i < caps.ulCaptureResCount; i++) { 145 if (supported[0] != '\0') { 146 strncat(supported, PARAM_SEP, 1); 147 } 148 strncat (supported, caps.tCaptureRes[i].param, MAX_PROP_VALUE_LENGTH-1 ); 149 } 150 params->set(CameraProperties::SUPPORTED_PICTURE_SIZES, supported); 151 return NO_ERROR; 152 } 153 154 status_t V4LCameraAdapter::insertFrameRates(CameraProperties::Properties* params, V4L_TI_CAPTYPE &caps) { 155 156 char supported[MAX_PROP_VALUE_LENGTH]; 157 char temp[10]; 158 159 memset(supported, '\0', MAX_PROP_VALUE_LENGTH); 160 for (int i = 0; i < caps.ulFrameRateCount; i++) { 161 snprintf (temp, 10, "%d", caps.ulFrameRates[i] ); 162 if (supported[0] != '\0') { 163 strncat(supported, PARAM_SEP, 1); 164 } 165 strncat (supported, temp, MAX_PROP_VALUE_LENGTH-1 ); 166 } 167 168 params->set(CameraProperties::SUPPORTED_PREVIEW_FRAME_RATES, supported); 169 return NO_ERROR; 170 } 171 172 status_t V4LCameraAdapter::insertCapabilities(CameraProperties::Properties* params, V4L_TI_CAPTYPE &caps) 173 { 174 status_t ret = NO_ERROR; 175 176 LOG_FUNCTION_NAME; 177 178 if ( NO_ERROR == ret ) { 179 ret = insertPreviewFormats(params, caps); 180 } 181 182 if ( NO_ERROR == ret ) { 183 ret = insertImageSizes(params, caps); 184 } 185 186 if ( NO_ERROR == ret ) { 187 ret = insertPreviewSizes(params, caps); 188 } 189 190 if ( NO_ERROR == ret ) { 191 ret = insertFrameRates(params, caps); 192 } 193 194 //Insert Supported Focus modes. 195 params->set(CameraProperties::SUPPORTED_FOCUS_MODES, "infinity"); 196 197 params->set(CameraProperties::SUPPORTED_PICTURE_FORMATS, "jpeg"); 198 199 if ( NO_ERROR == ret ) { 200 ret = insertDefaults(params, caps); 201 } 202 203 LOG_FUNCTION_NAME_EXIT; 204 205 return ret; 206 } 207 208 status_t V4LCameraAdapter::sortAscend(V4L_TI_CAPTYPE &caps, uint16_t count) { 209 size_t tempRes; 210 size_t w, h, tmpW,tmpH; 211 for (int i=0; i<count; i++) { 212 w = caps.tPreviewRes[i].width; 213 h = caps.tPreviewRes[i].height; 214 tempRes = w*h; 215 for (int j=i+1; j<count; j++) { 216 tmpW = caps.tPreviewRes[j].width; 217 tmpH = caps.tPreviewRes[j].height; 218 219 if (tempRes > (tmpW * tmpH) ) { 220 caps.tPreviewRes[j].width = w; 221 caps.tPreviewRes[j].height = h; 222 w = tmpW; 223 h = tmpH; 224 } 225 } 226 caps.tPreviewRes[i].width = w; 227 caps.tPreviewRes[i].height = h; 228 229 } 230 return NO_ERROR; 231 } 232 233 /***************************************** 234 * public exposed function declarations 235 *****************************************/ 236 237 status_t V4LCameraAdapter::getCaps(const int sensorId, CameraProperties::Properties* params, 238 V4L_HANDLETYPE handle) { 239 status_t status = NO_ERROR; 240 V4L_TI_CAPTYPE caps; 241 int i = 0; 242 int j = 0; 243 struct v4l2_fmtdesc fmtDesc; 244 struct v4l2_frmsizeenum frmSizeEnum; 245 struct v4l2_frmivalenum frmIvalEnum; 246 247 //get supported pixel formats 248 for ( i = 0; status == NO_ERROR; i++) { 249 fmtDesc.index = i; 250 fmtDesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 251 status = ioctl (handle, VIDIOC_ENUM_FMT, &fmtDesc); 252 if (status == NO_ERROR) { 253 CAMHAL_LOGDB("fmtDesc[%d].description::pixelformat::flags== (%s::%d::%d)",i, fmtDesc.description,fmtDesc.pixelformat,fmtDesc.flags); 254 caps.ePreviewFormats[i] = fmtDesc.pixelformat; 255 } 256 } 257 caps.ulPreviewFormatCount = i; 258 259 //get preview sizes & capture image sizes 260 status = NO_ERROR; 261 for ( i = 0; status == NO_ERROR; i++) { 262 frmSizeEnum.index = i; 263 //Check for frame sizes for default pixel format 264 //TODO: Check for frame sizes for all supported pixel formats 265 frmSizeEnum.pixel_format = V4L2_PIX_FMT_YUYV; 266 status = ioctl (handle, VIDIOC_ENUM_FRAMESIZES, &frmSizeEnum); 267 if (status == NO_ERROR) { 268 int width; 269 int height; 270 271 if(frmSizeEnum.type != V4L2_FRMSIZE_TYPE_DISCRETE) { 272 CAMHAL_LOGDB("\nfrmSizeEnum.type = %d", frmSizeEnum.type); 273 CAMHAL_LOGDB("\nmin_width x height = %d x %d ",frmSizeEnum.stepwise.min_width, frmSizeEnum.stepwise.min_height); 274 CAMHAL_LOGDB("\nmax_width x height = %d x %d ",frmSizeEnum.stepwise.max_width, frmSizeEnum.stepwise.max_height); 275 CAMHAL_LOGDB("\nstep width x height = %d x %d ",frmSizeEnum.stepwise.step_width,frmSizeEnum.stepwise.step_height); 276 //TODO: validate populating the sizes when type = V4L2_FRMSIZE_TYPE_STEPWISE 277 width = frmSizeEnum.stepwise.max_width; 278 height = frmSizeEnum.stepwise.max_height; 279 } 280 else { 281 CAMHAL_LOGDB("frmSizeEnum.index[%d].width x height == (%d x %d)", i, frmSizeEnum.discrete.width, frmSizeEnum.discrete.height); 282 width = frmSizeEnum.discrete.width; 283 height = frmSizeEnum.discrete.height; 284 } 285 286 caps.tCaptureRes[i].width = width; 287 caps.tCaptureRes[i].height = height; 288 caps.tPreviewRes[i].width = width; 289 caps.tPreviewRes[i].height = height; 290 291 snprintf(caps.tPreviewRes[i].param, MAX_RES_STRING_LENGTH,"%dx%d",caps.tPreviewRes[i].width,caps.tPreviewRes[i].height); 292 snprintf(caps.tCaptureRes[i].param, MAX_RES_STRING_LENGTH,"%dx%d",caps.tCaptureRes[i].width,caps.tCaptureRes[i].height); 293 } 294 else { 295 caps.ulCaptureResCount = i; 296 caps.ulPreviewResCount = i; 297 } 298 } 299 300 //sort the preview sizes in ascending order 301 sortAscend(caps, caps.ulPreviewResCount); 302 303 //get supported frame rates 304 bool fps30 = false; 305 for ( j=caps.ulPreviewResCount-1; j >= 0; j--) { 306 CAMHAL_LOGDB(" W x H = %d x %d", caps.tPreviewRes[j].width, caps.tPreviewRes[j].height); 307 status = NO_ERROR; 308 for ( i = 0; status == NO_ERROR; i++) { 309 frmIvalEnum.index = i; 310 //Check for supported frame rates for the default pixel format. 311 frmIvalEnum.pixel_format = V4L2_PIX_FMT_YUYV; 312 frmIvalEnum.width = caps.tPreviewRes[j].width; 313 frmIvalEnum.height = caps.tPreviewRes[j].height; 314 315 status = ioctl (handle, VIDIOC_ENUM_FRAMEINTERVALS, &frmIvalEnum); 316 if (status == NO_ERROR) { 317 if(frmIvalEnum.type != V4L2_FRMIVAL_TYPE_DISCRETE) { 318 CAMHAL_LOGDB("frmIvalEnum[%d].type = %d)", i, frmIvalEnum.type); 319 CAMHAL_LOGDB("frmIvalEnum[%d].stepwise.min = %d/%d)", i, frmIvalEnum.stepwise.min.denominator, frmIvalEnum.stepwise.min.numerator); 320 CAMHAL_LOGDB("frmIvalEnum[%d].stepwise.max = %d/%d)", i, frmIvalEnum.stepwise.max.denominator, frmIvalEnum.stepwise.max.numerator); 321 CAMHAL_LOGDB("frmIvalEnum[%d].stepwise.step = %d/%d)", i, frmIvalEnum.stepwise.step.denominator, frmIvalEnum.stepwise.step.numerator); 322 caps.ulFrameRates[i] = (frmIvalEnum.stepwise.max.denominator/frmIvalEnum.stepwise.max.numerator); 323 } 324 else { 325 CAMHAL_LOGDB("frmIvalEnum[%d].frame rate= %d)",i, (frmIvalEnum.discrete.denominator/frmIvalEnum.discrete.numerator)); 326 caps.ulFrameRates[i] = (frmIvalEnum.discrete.denominator/frmIvalEnum.discrete.numerator); 327 } 328 329 if (caps.ulFrameRates[i] == 30) { 330 fps30 = true; 331 } 332 } 333 else if (i == 0) { 334 // Framerate reporting is not guaranteed in V4L2 implementation. 335 caps.ulFrameRates[i] = 30; 336 fps30 = true; 337 caps.ulFrameRateCount = 1; 338 } else { 339 CAMHAL_LOGE("caps.ulFrameRateCount = %d",i); 340 caps.ulFrameRateCount = i; 341 } 342 } 343 if(fps30) { 344 break; 345 } 346 } 347 348 if(frmIvalEnum.type != V4L2_FRMIVAL_TYPE_DISCRETE) { 349 //TODO: populate the frame rates when type = V4L2_FRMIVAL_TYPE_STEPWISE; 350 } 351 352 //update the preview resolution with the highest resolution which supports 30fps. 353 /* // for video preview the application choose the resolution from the mediaprofiles.xml. 354 // so populating all supported preview resolution is required for video mode. 355 caps.tPreviewRes[0].width = caps.tPreviewRes[j].width; 356 caps.tPreviewRes[0].height = caps.tPreviewRes[j].height; 357 snprintf(caps.tPreviewRes[0].param, MAX_RES_STRING_LENGTH,"%dx%d",caps.tPreviewRes[j].width,caps.tPreviewRes[j].height); 358 caps.ulPreviewResCount = 1; 359 */ 360 insertCapabilities (params, caps); 361 return NO_ERROR; 362 } 363 364 365 366 } // namespace Camera 367 } // namespace Ti 368