mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-21 15:19:53 +01:00
Try harder to find suitable camera parameters. #346
This commit is contained in:
@@ -8,24 +8,24 @@ import android.hardware.Camera.Parameters;
|
|||||||
import android.hardware.Camera.Size;
|
import android.hardware.Camera.Size;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.DisplayMetrics;
|
|
||||||
import android.view.SurfaceHolder;
|
import android.view.SurfaceHolder;
|
||||||
import android.view.SurfaceView;
|
import android.view.SurfaceView;
|
||||||
|
|
||||||
import org.briarproject.android.util.PreviewConsumer;
|
import org.briarproject.android.util.PreviewConsumer;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import static android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT;
|
import static android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT;
|
||||||
|
import static android.hardware.Camera.Parameters.FLASH_MODE_OFF;
|
||||||
import static android.hardware.Camera.Parameters.FOCUS_MODE_AUTO;
|
import static android.hardware.Camera.Parameters.FOCUS_MODE_AUTO;
|
||||||
import static android.hardware.Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE;
|
import static android.hardware.Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE;
|
||||||
import static android.hardware.Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO;
|
import static android.hardware.Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO;
|
||||||
import static android.hardware.Camera.Parameters.FOCUS_MODE_EDOF;
|
import static android.hardware.Camera.Parameters.FOCUS_MODE_EDOF;
|
||||||
import static android.hardware.Camera.Parameters.FOCUS_MODE_FIXED;
|
import static android.hardware.Camera.Parameters.FOCUS_MODE_FIXED;
|
||||||
import static android.hardware.Camera.Parameters.FOCUS_MODE_MACRO;
|
import static android.hardware.Camera.Parameters.FOCUS_MODE_MACRO;
|
||||||
|
import static android.hardware.Camera.Parameters.SCENE_MODE_AUTO;
|
||||||
import static android.hardware.Camera.Parameters.SCENE_MODE_BARCODE;
|
import static android.hardware.Camera.Parameters.SCENE_MODE_BARCODE;
|
||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
@@ -75,10 +75,23 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
|
|||||||
this.camera = camera;
|
this.camera = camera;
|
||||||
this.previewConsumer = previewConsumer;
|
this.previewConsumer = previewConsumer;
|
||||||
setDisplayOrientation(rotationDegrees);
|
setDisplayOrientation(rotationDegrees);
|
||||||
|
// Use barcode scene mode if it's available
|
||||||
Parameters params = camera.getParameters();
|
Parameters params = camera.getParameters();
|
||||||
setFocusMode(params);
|
params = setSceneMode(camera, params);
|
||||||
setPreviewSize(params);
|
if (SCENE_MODE_BARCODE.equals(params.getSceneMode())) {
|
||||||
applyParameters(params);
|
// If the scene mode enabled the flash, try to disable it
|
||||||
|
if (!FLASH_MODE_OFF.equals(params.getFlashMode()))
|
||||||
|
params = disableFlash(camera, params);
|
||||||
|
// If the flash is still enabled, disable the scene mode
|
||||||
|
if (!FLASH_MODE_OFF.equals(params.getFlashMode()))
|
||||||
|
params = disableSceneMode(camera, params);
|
||||||
|
}
|
||||||
|
// Use the best available focus mode, preview size and other options
|
||||||
|
params = setBestParameters(camera, params);
|
||||||
|
// Enable auto focus if the selected focus mode uses it
|
||||||
|
enableAutoFocus(params.getFocusMode());
|
||||||
|
// Log the parameters that are being used (maybe not what we asked for)
|
||||||
|
logCameraParameters();
|
||||||
if (surfaceExists) startPreview(getHolder());
|
if (surfaceExists) startPreview(getHolder());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,55 +158,67 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
|
|||||||
displayOrientation = orientation;
|
displayOrientation = orientation;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setFocusMode(Parameters params) {
|
private Parameters setSceneMode(Camera camera, Parameters params) {
|
||||||
|
List<String> sceneModes = params.getSupportedSceneModes();
|
||||||
|
if (sceneModes == null) return params;
|
||||||
|
if (LOG.isLoggable(INFO)) LOG.info("Scene modes: " + sceneModes);
|
||||||
|
if (sceneModes.contains(SCENE_MODE_BARCODE)) {
|
||||||
|
params.setSceneMode(SCENE_MODE_BARCODE);
|
||||||
|
camera.setParameters(params);
|
||||||
|
return camera.getParameters();
|
||||||
|
}
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Parameters disableFlash(Camera camera, Parameters params) {
|
||||||
|
params.setFlashMode(FLASH_MODE_OFF);
|
||||||
|
camera.setParameters(params);
|
||||||
|
return camera.getParameters();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Parameters disableSceneMode(Camera camera, Parameters params) {
|
||||||
|
params.setSceneMode(SCENE_MODE_AUTO);
|
||||||
|
camera.setParameters(params);
|
||||||
|
return camera.getParameters();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Parameters setBestParameters(Camera camera, Parameters params) {
|
||||||
|
setVideoStabilisation(params);
|
||||||
|
setFocusMode(params);
|
||||||
|
params.setFlashMode(FLASH_MODE_OFF);
|
||||||
|
setPreviewSize(params);
|
||||||
|
camera.setParameters(params);
|
||||||
|
return camera.getParameters();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setVideoStabilisation(Parameters params) {
|
||||||
if (Build.VERSION.SDK_INT >= 15 &&
|
if (Build.VERSION.SDK_INT >= 15 &&
|
||||||
params.isVideoStabilizationSupported()) {
|
params.isVideoStabilizationSupported()) {
|
||||||
LOG.info("Enabling video stabilisation");
|
|
||||||
params.setVideoStabilization(true);
|
params.setVideoStabilization(true);
|
||||||
}
|
}
|
||||||
// This returns null on the HTC Wildfire S
|
}
|
||||||
List<String> sceneModes = params.getSupportedSceneModes();
|
|
||||||
if (sceneModes == null) sceneModes = Collections.emptyList();
|
private void setFocusMode(Parameters params) {
|
||||||
List<String> focusModes = params.getSupportedFocusModes();
|
List<String> focusModes = params.getSupportedFocusModes();
|
||||||
if (LOG.isLoggable(INFO)) {
|
if (LOG.isLoggable(INFO)) LOG.info("Focus modes: " + focusModes);
|
||||||
LOG.info("Scene modes: " + sceneModes);
|
|
||||||
LOG.info("Focus modes: " + focusModes);
|
|
||||||
}
|
|
||||||
if (sceneModes.contains(SCENE_MODE_BARCODE)) {
|
|
||||||
LOG.info("Setting scene mode to barcode");
|
|
||||||
params.setSceneMode(SCENE_MODE_BARCODE);
|
|
||||||
}
|
|
||||||
if (focusModes.contains(FOCUS_MODE_CONTINUOUS_PICTURE)) {
|
if (focusModes.contains(FOCUS_MODE_CONTINUOUS_PICTURE)) {
|
||||||
LOG.info("Setting focus mode to continuous picture");
|
|
||||||
params.setFocusMode(FOCUS_MODE_CONTINUOUS_PICTURE);
|
params.setFocusMode(FOCUS_MODE_CONTINUOUS_PICTURE);
|
||||||
} else if (focusModes.contains(FOCUS_MODE_CONTINUOUS_VIDEO)) {
|
} else if (focusModes.contains(FOCUS_MODE_CONTINUOUS_VIDEO)) {
|
||||||
LOG.info("Setting focus mode to continuous video");
|
|
||||||
params.setFocusMode(FOCUS_MODE_CONTINUOUS_VIDEO);
|
params.setFocusMode(FOCUS_MODE_CONTINUOUS_VIDEO);
|
||||||
} else if (focusModes.contains(FOCUS_MODE_EDOF)) {
|
} else if (focusModes.contains(FOCUS_MODE_EDOF)) {
|
||||||
LOG.info("Setting focus mode to EDOF");
|
|
||||||
params.setFocusMode(FOCUS_MODE_EDOF);
|
params.setFocusMode(FOCUS_MODE_EDOF);
|
||||||
} else if (focusModes.contains(FOCUS_MODE_MACRO)) {
|
} else if (focusModes.contains(FOCUS_MODE_MACRO)) {
|
||||||
LOG.info("Setting focus mode to macro");
|
|
||||||
params.setFocusMode(FOCUS_MODE_MACRO);
|
params.setFocusMode(FOCUS_MODE_MACRO);
|
||||||
autoFocus = true;
|
|
||||||
} else if (focusModes.contains(FOCUS_MODE_AUTO)) {
|
} else if (focusModes.contains(FOCUS_MODE_AUTO)) {
|
||||||
LOG.info("Setting focus mode to auto");
|
|
||||||
params.setFocusMode(FOCUS_MODE_AUTO);
|
params.setFocusMode(FOCUS_MODE_AUTO);
|
||||||
autoFocus = true;
|
|
||||||
} else if (focusModes.contains(FOCUS_MODE_FIXED)) {
|
} else if (focusModes.contains(FOCUS_MODE_FIXED)) {
|
||||||
LOG.info("Setting focus mode to fixed");
|
|
||||||
params.setFocusMode(FOCUS_MODE_FIXED);
|
params.setFocusMode(FOCUS_MODE_FIXED);
|
||||||
} else {
|
|
||||||
LOG.info("No suitable focus mode");
|
|
||||||
}
|
}
|
||||||
params.setZoom(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setPreviewSize(Parameters params) {
|
private void setPreviewSize(Parameters params) {
|
||||||
if (surfaceWidth == 0 || surfaceHeight == 0) return;
|
if (surfaceWidth == 0 || surfaceHeight == 0) return;
|
||||||
float idealRatio = (float) surfaceWidth / surfaceHeight;
|
float idealRatio = (float) surfaceWidth / surfaceHeight;
|
||||||
DisplayMetrics screen = getContext().getResources().getDisplayMetrics();
|
|
||||||
int screenMax = Math.max(screen.widthPixels, screen.heightPixels);
|
|
||||||
boolean rotatePreview = displayOrientation % 180 == 90;
|
boolean rotatePreview = displayOrientation % 180 == 90;
|
||||||
List<Size> sizes = params.getSupportedPreviewSizes();
|
List<Size> sizes = params.getSupportedPreviewSizes();
|
||||||
Size bestSize = null;
|
Size bestSize = null;
|
||||||
@@ -204,7 +229,7 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
|
|||||||
float ratio = (float) width / height;
|
float ratio = (float) width / height;
|
||||||
float stretch = Math.max(ratio / idealRatio, idealRatio / ratio);
|
float stretch = Math.max(ratio / idealRatio, idealRatio / ratio);
|
||||||
int pixels = width * height;
|
int pixels = width * height;
|
||||||
float score = width * height / stretch;
|
float score = pixels / stretch;
|
||||||
if (LOG.isLoggable(INFO)) {
|
if (LOG.isLoggable(INFO)) {
|
||||||
LOG.info("Size " + size.width + "x" + size.height
|
LOG.info("Size " + size.width + "x" + size.height
|
||||||
+ ", stretch " + stretch + ", pixels " + pixels
|
+ ", stretch " + stretch + ", pixels " + pixels
|
||||||
@@ -222,20 +247,34 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyParameters(Parameters params) {
|
private void enableAutoFocus(String focusMode) {
|
||||||
try {
|
autoFocus = FOCUS_MODE_AUTO.equals(focusMode) ||
|
||||||
camera.setParameters(params);
|
FOCUS_MODE_MACRO.equals(focusMode);
|
||||||
} catch (RuntimeException e) {
|
}
|
||||||
LOG.log(WARNING, "Error setting camera parameters", e);
|
|
||||||
|
private void logCameraParameters() {
|
||||||
|
if (LOG.isLoggable(INFO)) {
|
||||||
|
Parameters params = camera.getParameters();
|
||||||
|
if (Build.VERSION.SDK_INT >= 15) {
|
||||||
|
LOG.info("Video stabilisation enabled: "
|
||||||
|
+ params.getVideoStabilization());
|
||||||
|
}
|
||||||
|
LOG.info("Scene mode: " + params.getSceneMode());
|
||||||
|
LOG.info("Focus mode: " + params.getFocusMode());
|
||||||
|
LOG.info("Flash mode: " + params.getFlashMode());
|
||||||
|
Size size = params.getPreviewSize();
|
||||||
|
LOG.info("Preview size: " + size.width + "x" + size.height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void surfaceCreated(SurfaceHolder holder) {
|
public void surfaceCreated(SurfaceHolder holder) {
|
||||||
LOG.info("Surface created");
|
LOG.info("Surface created");
|
||||||
surfaceExists = true;
|
surfaceExists = true;
|
||||||
if (camera != null) startPreview(holder);
|
if (camera != null) startPreview(holder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
|
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
|
||||||
if (LOG.isLoggable(INFO)) LOG.info("Surface changed: " + w + "x" + h);
|
if (LOG.isLoggable(INFO)) LOG.info("Surface changed: " + w + "x" + h);
|
||||||
surfaceWidth = w;
|
surfaceWidth = w;
|
||||||
@@ -245,21 +284,25 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
|
|||||||
try {
|
try {
|
||||||
Parameters params = camera.getParameters();
|
Parameters params = camera.getParameters();
|
||||||
setPreviewSize(params);
|
setPreviewSize(params);
|
||||||
applyParameters(params);
|
camera.setParameters(params);
|
||||||
|
logCameraParameters();
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
LOG.log(WARNING, "Error getting camera parameters", e);
|
LOG.log(WARNING, "Error setting preview size", e);
|
||||||
}
|
}
|
||||||
startPreview(holder);
|
startPreview(holder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||||
LOG.info("Surface destroyed");
|
LOG.info("Surface destroyed");
|
||||||
surfaceExists = false;
|
surfaceExists = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void onAutoFocus(boolean success, final Camera camera) {
|
public void onAutoFocus(boolean success, final Camera camera) {
|
||||||
LOG.info("Auto focus succeeded: " + success);
|
LOG.info("Auto focus succeeded: " + success);
|
||||||
postDelayed(new Runnable() {
|
postDelayed(new Runnable() {
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
retryAutoFocus();
|
retryAutoFocus();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user