summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Sanders <nsanders@google.com>2012-11-06 15:46:24 -0800
committerNick Sanders <nsanders@google.com>2012-11-07 12:36:04 -0800
commit12352371033cc2426b27f5505aa8d25488eb674a (patch)
tree4a4199f84fdc2f9262fb4589a1cbfa6853a16b08
parent25df2c673b1cdecd6d97f5c46905f58a834c9bdd (diff)
downloadomap4-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.cpp67
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;
}
}