mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-13 11:19:04 +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.os.Build;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
|
||||
import org.briarproject.android.util.PreviewConsumer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
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_CONTINUOUS_PICTURE;
|
||||
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_FIXED;
|
||||
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 java.util.logging.Level.INFO;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
@@ -75,10 +75,23 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
|
||||
this.camera = camera;
|
||||
this.previewConsumer = previewConsumer;
|
||||
setDisplayOrientation(rotationDegrees);
|
||||
// Use barcode scene mode if it's available
|
||||
Parameters params = camera.getParameters();
|
||||
setFocusMode(params);
|
||||
setPreviewSize(params);
|
||||
applyParameters(params);
|
||||
params = setSceneMode(camera, params);
|
||||
if (SCENE_MODE_BARCODE.equals(params.getSceneMode())) {
|
||||
// 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());
|
||||
}
|
||||
|
||||
@@ -145,55 +158,67 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
|
||||
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 &&
|
||||
params.isVideoStabilizationSupported()) {
|
||||
LOG.info("Enabling video stabilisation");
|
||||
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();
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
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 (LOG.isLoggable(INFO)) LOG.info("Focus modes: " + focusModes);
|
||||
if (focusModes.contains(FOCUS_MODE_CONTINUOUS_PICTURE)) {
|
||||
LOG.info("Setting focus mode to continuous picture");
|
||||
params.setFocusMode(FOCUS_MODE_CONTINUOUS_PICTURE);
|
||||
} else if (focusModes.contains(FOCUS_MODE_CONTINUOUS_VIDEO)) {
|
||||
LOG.info("Setting focus mode to continuous video");
|
||||
params.setFocusMode(FOCUS_MODE_CONTINUOUS_VIDEO);
|
||||
} else if (focusModes.contains(FOCUS_MODE_EDOF)) {
|
||||
LOG.info("Setting focus mode to EDOF");
|
||||
params.setFocusMode(FOCUS_MODE_EDOF);
|
||||
} else if (focusModes.contains(FOCUS_MODE_MACRO)) {
|
||||
LOG.info("Setting focus mode to macro");
|
||||
params.setFocusMode(FOCUS_MODE_MACRO);
|
||||
autoFocus = true;
|
||||
} else if (focusModes.contains(FOCUS_MODE_AUTO)) {
|
||||
LOG.info("Setting focus mode to auto");
|
||||
params.setFocusMode(FOCUS_MODE_AUTO);
|
||||
autoFocus = true;
|
||||
} else if (focusModes.contains(FOCUS_MODE_FIXED)) {
|
||||
LOG.info("Setting focus mode to fixed");
|
||||
params.setFocusMode(FOCUS_MODE_FIXED);
|
||||
} else {
|
||||
LOG.info("No suitable focus mode");
|
||||
}
|
||||
params.setZoom(0);
|
||||
}
|
||||
|
||||
private void setPreviewSize(Parameters params) {
|
||||
if (surfaceWidth == 0 || surfaceHeight == 0) return;
|
||||
float idealRatio = (float) surfaceWidth / surfaceHeight;
|
||||
DisplayMetrics screen = getContext().getResources().getDisplayMetrics();
|
||||
int screenMax = Math.max(screen.widthPixels, screen.heightPixels);
|
||||
boolean rotatePreview = displayOrientation % 180 == 90;
|
||||
List<Size> sizes = params.getSupportedPreviewSizes();
|
||||
Size bestSize = null;
|
||||
@@ -204,7 +229,7 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
|
||||
float ratio = (float) width / height;
|
||||
float stretch = Math.max(ratio / idealRatio, idealRatio / ratio);
|
||||
int pixels = width * height;
|
||||
float score = width * height / stretch;
|
||||
float score = pixels / stretch;
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
LOG.info("Size " + size.width + "x" + size.height
|
||||
+ ", stretch " + stretch + ", pixels " + pixels
|
||||
@@ -222,20 +247,34 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
|
||||
}
|
||||
}
|
||||
|
||||
private void applyParameters(Parameters params) {
|
||||
try {
|
||||
camera.setParameters(params);
|
||||
} catch (RuntimeException e) {
|
||||
LOG.log(WARNING, "Error setting camera parameters", e);
|
||||
private void enableAutoFocus(String focusMode) {
|
||||
autoFocus = FOCUS_MODE_AUTO.equals(focusMode) ||
|
||||
FOCUS_MODE_MACRO.equals(focusMode);
|
||||
}
|
||||
|
||||
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) {
|
||||
LOG.info("Surface created");
|
||||
surfaceExists = true;
|
||||
if (camera != null) startPreview(holder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
|
||||
if (LOG.isLoggable(INFO)) LOG.info("Surface changed: " + w + "x" + h);
|
||||
surfaceWidth = w;
|
||||
@@ -245,21 +284,25 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
|
||||
try {
|
||||
Parameters params = camera.getParameters();
|
||||
setPreviewSize(params);
|
||||
applyParameters(params);
|
||||
camera.setParameters(params);
|
||||
logCameraParameters();
|
||||
} catch (RuntimeException e) {
|
||||
LOG.log(WARNING, "Error getting camera parameters", e);
|
||||
LOG.log(WARNING, "Error setting preview size", e);
|
||||
}
|
||||
startPreview(holder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||
LOG.info("Surface destroyed");
|
||||
surfaceExists = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAutoFocus(boolean success, final Camera camera) {
|
||||
LOG.info("Auto focus succeeded: " + success);
|
||||
postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
retryAutoFocus();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user