diff options
author | Nick Sanders <nsanders@google.com> | 2012-11-06 15:46:24 -0800 |
---|---|---|
committer | Nick Sanders <nsanders@google.com> | 2012-11-07 12:36:04 -0800 |
commit | 12352371033cc2426b27f5505aa8d25488eb674a (patch) | |
tree | 4a4199f84fdc2f9262fb4589a1cbfa6853a16b08 | |
parent | 25df2c673b1cdecd6d97f5c46905f58a834c9bdd (diff) | |
download | omap4-aah-12352371033cc2426b27f5505aa8d25488eb674a.tar.gz |
Fix error handling in caps query
Framerate and resolution queries to V4L2 may return different formats
or may not be specified. Avoid accessing the data before validating
the return code, and avoid corrupt data on unusual formats.
Change-Id: I525935192f36c635cbab8abc8d446a9c84812dae
-rw-r--r-- | camera/V4LCameraAdapter/V4LCapabilities.cpp | 67 |
1 files changed, 44 insertions, 23 deletions
diff --git a/camera/V4LCameraAdapter/V4LCapabilities.cpp b/camera/V4LCameraAdapter/V4LCapabilities.cpp index 3a84268..575f943 100644 --- a/camera/V4LCameraAdapter/V4LCapabilities.cpp +++ b/camera/V4LCameraAdapter/V4LCapabilities.cpp @@ -264,30 +264,38 @@ status_t V4LCameraAdapter::getCaps(const int sensorId, CameraProperties::Propert //TODO: Check for frame sizes for all supported pixel formats frmSizeEnum.pixel_format = V4L2_PIX_FMT_YUYV; status = ioctl (handle, VIDIOC_ENUM_FRAMESIZES, &frmSizeEnum); - if(frmSizeEnum.type != V4L2_FRMSIZE_TYPE_DISCRETE) { - break; - } if (status == NO_ERROR) { - CAMHAL_LOGDB("frmSizeEnum.index[%d].width x height == (%d x %d)", i, frmSizeEnum.discrete.width, frmSizeEnum.discrete.height); - caps.tPreviewRes[i].width = frmSizeEnum.discrete.width; - caps.tPreviewRes[i].height = frmSizeEnum.discrete.height; - snprintf(caps.tPreviewRes[i].param, MAX_RES_STRING_LENGTH,"%dx%d",frmSizeEnum.discrete.width,frmSizeEnum.discrete.height); - - caps.tCaptureRes[i].width = frmSizeEnum.discrete.width; - caps.tCaptureRes[i].height = frmSizeEnum.discrete.height; - snprintf(caps.tCaptureRes[i].param, MAX_RES_STRING_LENGTH,"%dx%d",frmSizeEnum.discrete.width,frmSizeEnum.discrete.height); + int width; + int height; + + if(frmSizeEnum.type != V4L2_FRMSIZE_TYPE_DISCRETE) { + CAMHAL_LOGDB("\nfrmSizeEnum.type = %d", frmSizeEnum.type); + CAMHAL_LOGDB("\nmin_width x height = %d x %d ",frmSizeEnum.stepwise.min_width, frmSizeEnum.stepwise.min_height); + CAMHAL_LOGDB("\nmax_width x height = %d x %d ",frmSizeEnum.stepwise.max_width, frmSizeEnum.stepwise.max_height); + CAMHAL_LOGDB("\nstep width x height = %d x %d ",frmSizeEnum.stepwise.step_width,frmSizeEnum.stepwise.step_height); + //TODO: validate populating the sizes when type = V4L2_FRMSIZE_TYPE_STEPWISE + width = frmSizeEnum.stepwise.max_width; + height = frmSizeEnum.stepwise.max_height; + } + else { + CAMHAL_LOGDB("frmSizeEnum.index[%d].width x height == (%d x %d)", i, frmSizeEnum.discrete.width, frmSizeEnum.discrete.height); + width = frmSizeEnum.discrete.width; + height = frmSizeEnum.discrete.height; + } + + caps.tCaptureRes[i].width = width; + caps.tCaptureRes[i].height = height; + caps.tPreviewRes[i].width = width; + caps.tPreviewRes[i].height = height; + + snprintf(caps.tPreviewRes[i].param, MAX_RES_STRING_LENGTH,"%dx%d",caps.tPreviewRes[i].width,caps.tPreviewRes[i].height); + snprintf(caps.tCaptureRes[i].param, MAX_RES_STRING_LENGTH,"%dx%d",caps.tCaptureRes[i].width,caps.tCaptureRes[i].height); } else { caps.ulCaptureResCount = i; caps.ulPreviewResCount = i; } } - if(frmSizeEnum.type != V4L2_FRMSIZE_TYPE_DISCRETE) { - CAMHAL_LOGDB("\nmin_width x height = %d x %d ",frmSizeEnum.stepwise.min_width, frmSizeEnum.stepwise.min_height); - CAMHAL_LOGDB("\nmax_width x height = %d x %d ",frmSizeEnum.stepwise.max_width, frmSizeEnum.stepwise.max_height); - CAMHAL_LOGDB("\nstep width x height = %d x %d ",frmSizeEnum.stepwise.step_width,frmSizeEnum.stepwise.step_height); - //TODO: populate the sizes when type = V4L2_FRMSIZE_TYPE_STEPWISE - } //sort the preview sizes in ascending order sortAscend(caps, caps.ulPreviewResCount); @@ -305,17 +313,30 @@ status_t V4LCameraAdapter::getCaps(const int sensorId, CameraProperties::Propert frmIvalEnum.height = caps.tPreviewRes[j].height; status = ioctl (handle, VIDIOC_ENUM_FRAMEINTERVALS, &frmIvalEnum); - if(frmIvalEnum.type != V4L2_FRMIVAL_TYPE_DISCRETE) { - break; - } if (status == NO_ERROR) { - CAMHAL_LOGDB("frmIvalEnum[%d].frame rate= %d)",i, (frmIvalEnum.discrete.denominator/frmIvalEnum.discrete.numerator)); - caps.ulFrameRates[i] = (frmIvalEnum.discrete.denominator/frmIvalEnum.discrete.numerator); + if(frmIvalEnum.type != V4L2_FRMIVAL_TYPE_DISCRETE) { + CAMHAL_LOGDB("frmIvalEnum[%d].type = %d)", i, frmIvalEnum.type); + CAMHAL_LOGDB("frmIvalEnum[%d].stepwise.min = %d/%d)", i, frmIvalEnum.stepwise.min.denominator, frmIvalEnum.stepwise.min.numerator); + CAMHAL_LOGDB("frmIvalEnum[%d].stepwise.max = %d/%d)", i, frmIvalEnum.stepwise.max.denominator, frmIvalEnum.stepwise.max.numerator); + CAMHAL_LOGDB("frmIvalEnum[%d].stepwise.step = %d/%d)", i, frmIvalEnum.stepwise.step.denominator, frmIvalEnum.stepwise.step.numerator); + caps.ulFrameRates[i] = (frmIvalEnum.stepwise.max.denominator/frmIvalEnum.stepwise.max.numerator); + } + else { + CAMHAL_LOGDB("frmIvalEnum[%d].frame rate= %d)",i, (frmIvalEnum.discrete.denominator/frmIvalEnum.discrete.numerator)); + caps.ulFrameRates[i] = (frmIvalEnum.discrete.denominator/frmIvalEnum.discrete.numerator); + } + if (caps.ulFrameRates[i] == 30) { fps30 = true; } } - else { + else if (i == 0) { + // Framerate reporting is not guaranteed in V4L2 implementation. + caps.ulFrameRates[i] = 30; + fps30 = true; + caps.ulFrameRateCount = 1; + } else { + CAMHAL_LOGE("caps.ulFrameRateCount = %d",i); caps.ulFrameRateCount = i; } } |