FP2: Fix underexposed OV5670 image sensor output
Previews, captured images and videos can turn out underexposed with the
OV5670 image sensor. This underexposure is caused by the capture frame
rate running at a fixed 30 frames per second. Instead the auto-exposure
routine can take a range, over which it can adjust the capture frame
rate to maintain good exposure.
Fix the issue by setting a target FPS range for the Fairphone 2 front
camera for all image captures, ranging from 7 to 30 FPS.
Issue: FP2P-587
Change-Id: Ia3dde2e9e5f6e2ee642222ffa0bce5659ad4db83
diff --git a/src/com/android/camera/VideoModule.java b/src/com/android/camera/VideoModule.java
index e8222f6..5707721 100644
--- a/src/com/android/camera/VideoModule.java
+++ b/src/com/android/camera/VideoModule.java
@@ -1654,8 +1654,14 @@
mCameraSettings.setSetting("video-size",
mProfile.videoFrameWidth + "x" + mProfile.videoFrameHeight);
}
- int[] fpsRange =
- CameraUtil.getMaxPreviewFpsRange(mCameraCapabilities.getSupportedPreviewFpsRange());
+
+ int[] fpsRange;
+ if (isCameraFrontFacing() && ApiHelper.IS_FAIRPHONE_2) {
+ fpsRange = CameraUtil.getPhotoPreviewFpsRange(mCameraCapabilities);
+ } else {
+ fpsRange = CameraUtil.getMaxPreviewFpsRange(mCameraCapabilities.getSupportedPreviewFpsRange());
+ }
+
if (fpsRange.length > 0) {
mCameraSettings.setPreviewFpsRange(fpsRange[0], fpsRange[1]);
} else {
diff --git a/src/com/android/camera/one/v2/SimpleOneCameraFactory.java b/src/com/android/camera/one/v2/SimpleOneCameraFactory.java
index 59d94cf..28bd20a 100644
--- a/src/com/android/camera/one/v2/SimpleOneCameraFactory.java
+++ b/src/com/android/camera/one/v2/SimpleOneCameraFactory.java
@@ -21,6 +21,7 @@
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CaptureRequest;
import android.os.Build;
+import android.util.Range;
import android.view.Surface;
import com.android.camera.FatalErrorHandler;
@@ -31,6 +32,8 @@
import com.android.camera.async.Observables;
import com.android.camera.async.Updatable;
import com.android.camera.burst.BurstFacade;
+import com.android.camera.debug.Log.Tag;
+import com.android.camera.debug.Logger;
import com.android.camera.debug.Loggers;
import com.android.camera.one.OneCamera;
import com.android.camera.one.OneCameraCharacteristics;
@@ -62,6 +65,7 @@
import com.android.camera.one.v2.sharedimagereader.SharedImageReaderFactory;
import com.android.camera.stats.UsageStatistics;
import com.android.camera.util.AndroidContext;
+import com.android.camera.util.ApiHelper;
import com.android.camera.util.GservicesHelper;
import com.android.camera.util.Provider;
import com.android.camera.util.Size;
@@ -79,6 +83,9 @@
*/
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class SimpleOneCameraFactory implements OneCameraFactory {
+ private static Tag TAG = new Tag("SimpleOneCameraFactory");
+
+ private final Logger mLogger;
private final int mImageFormat;
private final int mMaxImageCount;
private final ImageRotationCalculator mImageRotationCalculator;
@@ -94,6 +101,19 @@
mImageFormat = imageFormat;
mMaxImageCount = maxImageCount;
mImageRotationCalculator = imageRotationCalculator;
+ mLogger = Loggers.tagFactory().create(TAG);
+ }
+
+ /**
+ * Slows down the requested camera frame for Fairphone 2 front camera issue.
+ *
+ * @param requestTemplate Request template that will be applied to the
+ * current camera device
+ */
+ private void applyFairphone2FrontCameraFrameRateWorkaround(RequestTemplate requestTemplate) {
+ Range<Integer> frameRateBackOff = new Range<>(7, 30);
+ mLogger.v("Applying Fairphone2 specific framerate backoff of " + frameRateBackOff);
+ requestTemplate.setParam(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, frameRateBackOff);
}
@Override
@@ -175,6 +195,13 @@
FrameServer ephemeralFrameServer =
frameServerComponent.provideEphemeralFrameServer();
+ boolean isFrontCamera = characteristics.getCameraDirection() ==
+ OneCamera.Facing.FRONT;
+
+ if (isFrontCamera && ApiHelper.IS_FAIRPHONE_2) {
+ applyFairphone2FrontCameraFrameRateWorkaround(rootBuilder);
+ }
+
// Create basic functionality (zoom, AE, AF).
BasicCameraFactory basicCameraFactory = new BasicCameraFactory(new Lifetime
(cameraLifetime),
diff --git a/src/com/android/camera/util/ApiHelper.java b/src/com/android/camera/util/ApiHelper.java
index 471ee05..bab102a 100644
--- a/src/com/android/camera/util/ApiHelper.java
+++ b/src/com/android/camera/util/ApiHelper.java
@@ -71,6 +71,9 @@
&& ("flounder".equalsIgnoreCase(Build.DEVICE)
|| "flounder_lte".equalsIgnoreCase(Build.DEVICE));
+ public static final boolean IS_FAIRPHONE_2 = "Fairphone".equalsIgnoreCase(Build.MANUFACTURER)
+ && "FP2".equalsIgnoreCase(Build.DEVICE);
+
public static final boolean HAS_CAMERA_2_API = isLOrHigher();
public static int getIntFieldIfExists(Class<?> klass, String fieldName,