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
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 @@
         //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);
+            int width;
+            int 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);
+            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 @@
             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;
             }
         }