Camera: use rational/double for external camera framerate

For better precision.
Ex: minFrameDuration of 30fps 333333334->333333333

Bug: 72261912
Change-Id: I830d694d34eb01426e46279c4c986d8879b9d847
diff --git a/camera/device/3.4/default/ExternalCameraDevice.cpp b/camera/device/3.4/default/ExternalCameraDevice.cpp
index 61b8921..b6470f5 100644
--- a/camera/device/3.4/default/ExternalCameraDevice.cpp
+++ b/camera/device/3.4/default/ExternalCameraDevice.cpp
@@ -595,16 +595,19 @@
                     ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
         }
 
-        int64_t min_frame_duration = std::numeric_limits<int64_t>::max();
-        for (const auto& frameRate : supportedFormat.frameRates) {
-            int64_t frame_duration = 1000000000LL / frameRate;
-            if (frame_duration < min_frame_duration) {
-                min_frame_duration = frame_duration;
+        int64_t minFrameDuration = std::numeric_limits<int64_t>::max();
+        for (const auto& fr : supportedFormat.frameRates) {
+            // 1000000000LL < (2^32 - 1) and
+            // fr.durationNumerator is uint32_t, so no overflow here
+            int64_t frameDuration = 1000000000LL * fr.durationNumerator /
+                    fr.durationDenominator;
+            if (frameDuration < minFrameDuration) {
+                minFrameDuration = frameDuration;
             }
-            if (frame_duration > maxFrameDuration) {
-                maxFrameDuration = frame_duration;
+            if (frameDuration > maxFrameDuration) {
+                maxFrameDuration = frameDuration;
             }
-            int32_t frameRateInt = static_cast<int32_t>(frameRate);
+            int32_t frameRateInt = static_cast<int32_t>(fr.getDouble());
             if (minFps > frameRateInt) {
                 minFps = frameRateInt;
             }
@@ -618,7 +621,7 @@
             minFrameDurations.push_back(format);
             minFrameDurations.push_back(supportedFormat.width);
             minFrameDurations.push_back(supportedFormat.height);
-            minFrameDurations.push_back(min_frame_duration);
+            minFrameDurations.push_back(minFrameDuration);
         }
 
         // The stall duration is 0 for non-jpeg formats. For JPEG format, stall
@@ -705,8 +708,10 @@
             ++frameInterval.index) {
         if (frameInterval.type == V4L2_FRMIVAL_TYPE_DISCRETE) {
             if (frameInterval.discrete.numerator != 0) {
-                float framerate = frameInterval.discrete.denominator /
-                        static_cast<float>(frameInterval.discrete.numerator);
+                SupportedV4L2Format::FrameRate fr = {
+                        frameInterval.discrete.numerator,
+                        frameInterval.discrete.denominator};
+                double framerate = fr.getDouble();
                 if (framerate > fpsUpperBound) {
                     continue;
                 }
@@ -717,7 +722,7 @@
                     (frameInterval.pixel_format >> 16) & 0xFF,
                     (frameInterval.pixel_format >> 24) & 0xFF,
                     frameInterval.width, frameInterval.height, framerate);
-                format->frameRates.push_back(framerate);
+                format->frameRates.push_back(fr);
             }
         }
     }
diff --git a/camera/device/3.4/default/ExternalCameraDeviceSession.cpp b/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
index 74fd7f4..5de1442 100644
--- a/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
+++ b/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
@@ -1904,7 +1904,8 @@
     float fps = 1000.f;
     const float kDefaultFps = 30.f;
     // Try to pick the slowest fps that is at least 30
-    for (const auto& f : v4l2Fmt.frameRates) {
+    for (const auto& fr : v4l2Fmt.frameRates) {
+        double f = fr.getDouble();
         if (maxFps < f) {
             maxFps = f;
         }
@@ -2346,8 +2347,8 @@
     bool support30Fps = false;
     int32_t maxFps = std::numeric_limits<int32_t>::min();
     for (const auto& supportedFormat : mSupportedFormats) {
-        for (const auto& frameRate : supportedFormat.frameRates) {
-            int32_t framerateInt = static_cast<int32_t>(frameRate);
+        for (const auto& fr : supportedFormat.frameRates) {
+            int32_t framerateInt = static_cast<int32_t>(fr.getDouble());
             if (maxFps < framerateInt) {
                 maxFps = framerateInt;
             }
diff --git a/camera/device/3.4/default/ExternalCameraUtils.cpp b/camera/device/3.4/default/ExternalCameraUtils.cpp
index 80f296c..d28a4dd 100644
--- a/camera/device/3.4/default/ExternalCameraUtils.cpp
+++ b/camera/device/3.4/default/ExternalCameraUtils.cpp
@@ -147,6 +147,10 @@
     return (std::abs(ar1 - ar2) < kAspectRatioMatchThres);
 }
 
+double SupportedV4L2Format::FrameRate::getDouble() const {
+    return durationDenominator / static_cast<double>(durationNumerator);
+}
+
 }  // namespace implementation
 }  // namespace V3_4
 }  // namespace device
@@ -247,7 +251,7 @@
             limit.size = {
                 row->UnsignedAttribute("width", /*Default*/0),
                 row->UnsignedAttribute("height", /*Default*/0)};
-            limit.fpsUpperBound = row->FloatAttribute("fpsBound", /*Default*/1000.0);
+            limit.fpsUpperBound = row->DoubleAttribute("fpsBound", /*Default*/1000.0);
             if (limit.size.width <= prevLimit.size.width ||
                     limit.size.height <= prevLimit.size.height ||
                     limit.fpsUpperBound >= prevLimit.fpsUpperBound) {
diff --git a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h
index e56160a..37e7cfb 100644
--- a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h
+++ b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h
@@ -73,7 +73,7 @@
 
     struct FpsLimitation {
         Size size;
-        float fpsUpperBound;
+        double fpsUpperBound;
     };
     std::vector<FpsLimitation> fpsLimits;
 
@@ -93,7 +93,12 @@
     uint32_t height;
     uint32_t fourcc;
     // All supported frame rate for this w/h/fourcc combination
-    std::vector<float> frameRates;
+    struct FrameRate {
+        uint32_t durationNumerator;   // frame duration numerator.   Ex: 1
+        uint32_t durationDenominator; // frame duration denominator. Ex: 30
+        double getDouble() const;     // FrameRate in double.        Ex: 30.0
+    };
+    std::vector<FrameRate> frameRates;
 };
 
 // A class provide access to a dequeued V4L2 frame buffer (mostly in MJPG format)