You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
CameraView/camerakit/src/main/api21/com/flurgle/camerakit/Camera2.java

295 lines
8.6 KiB

package com.flurgle.camerakit;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.ImageFormat;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.support.annotation.Nullable;
import android.util.Log;
import android.util.SizeF;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.TreeSet;
@TargetApi(21)
class Camera2 extends CameraImpl {
private CameraDevice mCamera;
private CameraCharacteristics mCameraCharacteristics;
private CameraManager mCameraManager;
private String mCameraId;
private int mFacing;
private Size mCaptureSize;
private Size mPreviewSize;
private ConstantMapper.MapperImpl mMapper = new ConstantMapper.Mapper2();
private final HashMap<String, ExtraProperties> mExtraPropertiesMap = new HashMap<>();
Camera2(CameraListener callback, PreviewImpl preview, Context context) {
super(callback, preview);
preview.setCallback(new PreviewImpl.OnPreviewSurfaceChangedCallback() {
@Override
public void onPreviewSurfaceChanged() {
}
});
mCameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
// Get all view angles
try {
for (final String cameraId : mCameraManager.getCameraIdList()) {
CameraCharacteristics characteristics =
mCameraManager.getCameraCharacteristics(cameraId);
@SuppressWarnings("ConstantConditions")
int orientation = characteristics.get(CameraCharacteristics.LENS_FACING);
if (orientation == CameraCharacteristics.LENS_FACING_BACK) {
float[] maxFocus = characteristics.get(
CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS);
if (maxFocus == null) {
continue;
}
SizeF size = characteristics.get(
CameraCharacteristics.SENSOR_INFO_PHYSICAL_SIZE);
if (size == null) {
continue;
}
float w = size.getWidth();
float h = size.getHeight();
mExtraPropertiesMap.put(cameraId, new ExtraProperties(
(float) Math.toDegrees(2*Math.atan(w/(maxFocus[0]*2))),
(float) Math.toDegrees(2*Math.atan(h/(maxFocus[0]*2)))
));
}
}
} catch (CameraAccessException e) {
throw new RuntimeException("Failed to get camera view angles", e);
}
}
// CameraImpl:
@Override
void start() {
}
@Override
void stop() {
}
@Override
void onDisplayOffset(int displayOrientation) {
}
@Override
void onDeviceOrientation(int deviceOrientation) {
}
@Override
void setFacing(@Facing int facing) {
int internalFacing = mMapper.mapFacing(facing);
final String[] ids;
try {
ids = mCameraManager.getCameraIdList();
} catch (CameraAccessException e) {
Log.e("CameraKit", e.toString());
return;
}
if (ids.length == 0) {
throw new RuntimeException("No camera available.");
}
//
// for (String id : ids) {
// CameraCharacteristics cameraCharacteristics = mCameraManager.getCameraCharacteristics(id);
// Integer level = cameraCharacteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
// if (level == null || level == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {
// continue;
// }
// Integer internal = cameraCharacteristics.get(CameraCharacteristics.LENS_FACING);
// if (internal == null) {
// throw new NullPointerException("Unexpected state: LENS_FACING null");
// }
// if (internal == internalFacing) {
// mCameraId = id;
// mCameraCharacteristics = cameraCharacteristics;
// return true;
// }
// }
if (mFacing == facing && isCameraOpened()) {
stop();
start();
}
}
@Override
void setFlash(@Flash int flash) {
}
@Override
void setFocus(@Focus int focus) {
}
@Override
void setSessionType(@SessionType int sessionType) {
}
@Override
void setZoom(@ZoomMode int zoom) {
}
@Override
void setLocation(double latitude, double longitude) {
}
@Override
void setWhiteBalance(@WhiteBalance int whiteBalance) {
}
@Override
void setVideoQuality(int videoQuality) {
}
@Override
void captureImage() {
}
@Override
void startVideo() {
}
@Override
void endVideo() {
}
@Override
Size getCaptureSize() {
if (mCaptureSize == null && mCameraCharacteristics != null) {
TreeSet<Size> sizes = new TreeSet<>();
sizes.addAll(getAvailableCaptureResolutions());
TreeSet<AspectRatio> aspectRatios = new CommonAspectRatioFilter(
getAvailablePreviewResolutions(),
getAvailableCaptureResolutions()
).filter();
AspectRatio targetRatio = aspectRatios.size() > 0 ? aspectRatios.last() : null;
Iterator<Size> descendingSizes = sizes.descendingIterator();
Size size;
while (descendingSizes.hasNext() && mCaptureSize == null) {
size = descendingSizes.next();
if (targetRatio == null || targetRatio.matches(size)) {
mCaptureSize = size;
break;
}
}
}
return mCaptureSize;
}
@Override
Size getPreviewSize() {
if (mPreviewSize == null && mCameraCharacteristics != null) {
TreeSet<Size> sizes = new TreeSet<>();
sizes.addAll(getAvailablePreviewResolutions());
TreeSet<AspectRatio> aspectRatios = new CommonAspectRatioFilter(
getAvailablePreviewResolutions(),
getAvailableCaptureResolutions()
).filter();
AspectRatio targetRatio = aspectRatios.size() > 0 ? aspectRatios.last() : null;
Iterator<Size> descendingSizes = sizes.descendingIterator();
Size size;
while (descendingSizes.hasNext() && mPreviewSize == null) {
size = descendingSizes.next();
if (targetRatio == null || targetRatio.matches(size)) {
mPreviewSize = size;
break;
}
}
}
return mPreviewSize;
}
@Override
boolean shouldFlipSizes() {
return false;
}
@Override
boolean isCameraOpened() {
return mCamera != null;
}
@Nullable
@Override
ExtraProperties getExtraProperties() {
if (mCamera == null) {
return null;
}
return mExtraPropertiesMap.get(mCamera.getId());
}
// Internal
private List<Size> getAvailableCaptureResolutions() {
List<Size> output = new ArrayList<>();
if (mCameraCharacteristics != null) {
StreamConfigurationMap map = mCameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
if (map == null) {
throw new IllegalStateException("Failed to get configuration map: " + mCameraId);
}
for (android.util.Size size : map.getOutputSizes(ImageFormat.JPEG)) {
output.add(new Size(size.getWidth(), size.getHeight()));
}
}
return output;
}
private List<Size> getAvailablePreviewResolutions() {
List<Size> output = new ArrayList<>();
if (mCameraCharacteristics != null) {
StreamConfigurationMap map = mCameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
if (map == null) {
throw new IllegalStateException("Failed to get configuration map: " + mCameraId);
}
for (android.util.Size size : map.getOutputSizes(mPreview.getOutputClass())) {
output.add(new Size(size.getWidth(), size.getHeight()));
}
}
return output;
}
}