Home | History | Annotate | Download | only in V4LCameraAdapter
      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