diff options
author | Angus Kong <shkong@google.com> | 2014-04-22 16:39:42 -0700 |
---|---|---|
committer | Ed Heyl <edheyl@google.com> | 2014-06-18 10:24:45 -0700 |
commit | c36e3c983c232dc45ed31f3d8e98d8cdd7ac14ba (patch) | |
tree | 2a08cc88067dafb4fc0c4b96955c69cf4a3149b8 /camera2 | |
parent | 60520c4df78e595964605cf8acfa21bbafaeba84 (diff) | |
download | android_frameworks_ex-c36e3c983c232dc45ed31f3d8e98d8cdd7ac14ba.tar.gz android_frameworks_ex-c36e3c983c232dc45ed31f3d8e98d8cdd7ac14ba.tar.bz2 android_frameworks_ex-c36e3c983c232dc45ed31f3d8e98d8cdd7ac14ba.zip |
First Step: CameraCapabilities intead of Parameter
To get rid of Camera.Parameters, we need to provide our own interfaces.
Camera.Parameters actually consists of 2 parts: capabilities and settings. We'll
provide two interfaces and will just use Camera.Parameters inside of
CameraManager implementations.
Change-Id: I53922b6d740835412d74365374a6a0382129564e
Diffstat (limited to 'camera2')
5 files changed, 1044 insertions, 9 deletions
diff --git a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraCapabilities.java b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraCapabilities.java new file mode 100644 index 0000000..38e3f36 --- /dev/null +++ b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraCapabilities.java @@ -0,0 +1,451 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ex.camera2.portability; + +import android.graphics.Point; +import android.hardware.Camera; + +import com.android.ex.camera2.portability.debug.Log; + +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +/** + * The subclass of {@link CameraCapabilities} for Android Camera 1 API. + */ +public class AndroidCameraCapabilities extends CameraCapabilities { + + private static Log.Tag TAG = new Log.Tag("AndroidCameraCapabilities"); + + private FpsComparator mFpsComparator = new FpsComparator(); + private SizeComparator mSizeComparator = new SizeComparator(); + + AndroidCameraCapabilities(Camera.Parameters p) { + super(new AndroidCameraCapabilityStringifier()); + mMaxExposureCompensation = p.getMaxExposureCompensation(); + mMinExposureCompensation = p.getMinExposureCompensation(); + mExposureCompensationStep = p.getExposureCompensationStep(); + mMaxNumOfFacesSupported = p.getMaxNumDetectedFaces(); + mMaxNumOfMeteringArea = p.getMaxNumMeteringAreas(); + mSupportedPreviewFormats.addAll(p.getSupportedPreviewFormats()); + mSupportedPictureFormats.addAll(p.getSupportedPictureFormats()); + buildPreviewFpsRange(p); + buildPreviewSizes(p); + buildVideoSizes(p); + buildPictureSizes(p); + buildSceneModes(p); + buildFlashModes(p); + buildFocusModes(p); + buildWhiteBalances(p); + + if (p.isZoomSupported()) { + mSupportedFeatures.add(Feature.ZOOM); + } + if (p.isVideoSnapshotSupported()) { + mSupportedFeatures.add(Feature.VIDEO_SNAPSHOT); + } + if (p.isAutoExposureLockSupported()) { + mSupportedFeatures.add(Feature.AUTO_EXPOSURE_LOCK); + } + if (p.isAutoWhiteBalanceLockSupported()) { + mSupportedFeatures.add(Feature.AUTO_WHITE_BALANCE_LOCK); + } + if (supports(FocusMode.AUTO)) { + mMaxNumOfFocusAreas = p.getMaxNumFocusAreas(); + if (mMaxNumOfFocusAreas > 0) { + mSupportedFeatures.add(Feature.FOCUS_AREA); + } + } + if (mMaxNumOfMeteringArea > 0) { + mSupportedFeatures.add(Feature.METERING_AREA); + } + } + + AndroidCameraCapabilities(AndroidCameraCapabilities src) { + super(src); + } + + private void buildPreviewFpsRange(Camera.Parameters p) { + List<int[]> supportedPreviewFpsRange = p.getSupportedPreviewFpsRange(); + if (supportedPreviewFpsRange != null) { + mSupportedPreviewFpsRange.addAll(supportedPreviewFpsRange); + } + Collections.sort(mSupportedPreviewFpsRange, mFpsComparator); + } + + private void buildPreviewSizes(Camera.Parameters p) { + List<Camera.Size> supportedPreviewSizes = p.getSupportedPreviewSizes(); + if (supportedPreviewSizes != null) { + for (Camera.Size s : supportedPreviewSizes) { + mSupportedPreviewSizes.add(new Point(s.width, s.height)); + } + } + Collections.sort(mSupportedPreviewSizes, mSizeComparator); + } + + private void buildVideoSizes(Camera.Parameters p) { + List<Camera.Size> supportedVideoSizes = p.getSupportedVideoSizes(); + if (supportedVideoSizes != null) { + for (Camera.Size s : supportedVideoSizes) { + mSupportedVideoSizes.add(new Point(s.width, s.height)); + } + } + Collections.sort(mSupportedVideoSizes, mSizeComparator); + } + + private void buildPictureSizes(Camera.Parameters p) { + List<Camera.Size> supportedPictureSizes = p.getSupportedPictureSizes(); + if (supportedPictureSizes != null) { + for (Camera.Size s : supportedPictureSizes) { + mSupportedPictureSizes.add(new Point(s.width, s.height)); + } + } + Collections.sort(mSupportedPictureSizes, mSizeComparator); + + } + + private void buildSceneModes(Camera.Parameters p) { + List<String> supportedSceneModes = p.getSupportedSceneModes(); + if (supportedSceneModes != null) { + for (String scene : supportedSceneModes) { + if (Camera.Parameters.SCENE_MODE_AUTO.equals(scene)) { + mSupportedSceneModes.add(SceneMode.AUTO); + } else if (Camera.Parameters.SCENE_MODE_ACTION.equals(scene)) { + mSupportedSceneModes.add(SceneMode.ACTION); + } else if (Camera.Parameters.SCENE_MODE_BARCODE.equals(scene)) { + mSupportedSceneModes.add(SceneMode.BARCODE); + } else if (Camera.Parameters.SCENE_MODE_BEACH.equals(scene)) { + mSupportedSceneModes.add(SceneMode.BEACH); + } else if (Camera.Parameters.SCENE_MODE_CANDLELIGHT.equals(scene)) { + mSupportedSceneModes.add(SceneMode.CANDLELIGHT); + } else if (Camera.Parameters.SCENE_MODE_FIREWORKS.equals(scene)) { + mSupportedSceneModes.add(SceneMode.FIREWORKS); + } else if (Camera.Parameters.SCENE_MODE_HDR.equals(scene)) { + mSupportedSceneModes.add(SceneMode.HDR); + } else if (Camera.Parameters.SCENE_MODE_LANDSCAPE.equals(scene)) { + mSupportedSceneModes.add(SceneMode.LANDSCAPE); + } else if (Camera.Parameters.SCENE_MODE_NIGHT.equals(scene)) { + mSupportedSceneModes.add(SceneMode.NIGHT); + } else if (Camera.Parameters.SCENE_MODE_NIGHT_PORTRAIT.equals(scene)) { + mSupportedSceneModes.add(SceneMode.NIGHT_PORTRAIT); + } else if (Camera.Parameters.SCENE_MODE_PARTY.equals(scene)) { + mSupportedSceneModes.add(SceneMode.PARTY); + } else if (Camera.Parameters.SCENE_MODE_PORTRAIT.equals(scene)) { + mSupportedSceneModes.add(SceneMode.PORTRAIT); + } else if (Camera.Parameters.SCENE_MODE_SNOW.equals(scene)) { + mSupportedSceneModes.add(SceneMode.SNOW); + } else if (Camera.Parameters.SCENE_MODE_SPORTS.equals(scene)) { + mSupportedSceneModes.add(SceneMode.SPORTS); + } else if (Camera.Parameters.SCENE_MODE_STEADYPHOTO.equals(scene)) { + mSupportedSceneModes.add(SceneMode.STEADYPHOTO); + } else if (Camera.Parameters.SCENE_MODE_SUNSET.equals(scene)) { + mSupportedSceneModes.add(SceneMode.SUNSET); + } else if (Camera.Parameters.SCENE_MODE_THEATRE.equals(scene)) { + mSupportedSceneModes.add(SceneMode.THEATRE); + } + } + } + } + + private void buildFlashModes(Camera.Parameters p) { + List<String> supportedFlashModes = p.getSupportedFlashModes(); + if (supportedFlashModes != null) { + for (String flash : supportedFlashModes) { + if (Camera.Parameters.FLASH_MODE_AUTO.equals(flash)) { + mSupportedFlashModes.add(FlashMode.AUTO); + } else if (Camera.Parameters.FLASH_MODE_OFF.equals(flash)) { + mSupportedFlashModes.add(FlashMode.OFF); + } else if (Camera.Parameters.FLASH_MODE_ON.equals(flash)) { + mSupportedFlashModes.add(FlashMode.ON); + } else if (Camera.Parameters.FLASH_MODE_RED_EYE.equals(flash)) { + mSupportedFlashModes.add(FlashMode.RED_EYE); + } + } + } + } + + private void buildFocusModes(Camera.Parameters p) { + List<String> supportedFocusModes = p.getSupportedFocusModes(); + if (supportedFocusModes != null) { + for (String focus : supportedFocusModes) { + if (Camera.Parameters.FOCUS_MODE_AUTO.equals(focus)) { + mSupportedFocusModes.add(FocusMode.AUTO); + } else if (Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE.equals(focus)) { + mSupportedFocusModes.add(FocusMode.CONTINUOUS_PICTURE); + } else if (Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO.equals(focus)) { + mSupportedFocusModes.add(FocusMode.CONTINUOUS_VIDEO); + } else if (Camera.Parameters.FOCUS_MODE_EDOF.equals(focus)) { + mSupportedFocusModes.add(FocusMode.EXTENDED_DOF); + } else if (Camera.Parameters.FOCUS_MODE_FIXED.equals(focus)) { + mSupportedFocusModes.add(FocusMode.FIXED); + } else if (Camera.Parameters.FOCUS_MODE_INFINITY.equals(focus)) { + mSupportedFocusModes.add(FocusMode.INFINITY); + } else if (Camera.Parameters.FOCUS_MODE_MACRO.equals(focus)) { + mSupportedFocusModes.add(FocusMode.MACRO); + } + } + } + } + + private void buildWhiteBalances(Camera.Parameters p) { + List<String> supportedWhiteBalances = p.getSupportedFocusModes(); + if (supportedWhiteBalances != null) { + for (String wb : supportedWhiteBalances) { + if (Camera.Parameters.WHITE_BALANCE_AUTO.equals(wb)) { + mSupportedWhiteBalances.add(WhiteBalance.AUTO); + } else if (Camera.Parameters.WHITE_BALANCE_CLOUDY_DAYLIGHT.equals(wb)) { + mSupportedWhiteBalances.add(WhiteBalance.CLOUDY_DAYLIGHT); + } else if (Camera.Parameters.WHITE_BALANCE_DAYLIGHT.equals(wb)) { + mSupportedWhiteBalances.add(WhiteBalance.DAYLIGHT); + } else if (Camera.Parameters.WHITE_BALANCE_FLUORESCENT.equals(wb)) { + mSupportedWhiteBalances.add(WhiteBalance.FLUORESCENT); + } else if (Camera.Parameters.WHITE_BALANCE_INCANDESCENT.equals(wb)) { + mSupportedWhiteBalances.add(WhiteBalance.INCANDESCENT); + } else if (Camera.Parameters.WHITE_BALANCE_SHADE.equals(wb)) { + mSupportedWhiteBalances.add(WhiteBalance.SHADE); + } else if (Camera.Parameters.WHITE_BALANCE_TWILIGHT.equals(wb)) { + mSupportedWhiteBalances.add(WhiteBalance.TWILIGHT); + } else if (Camera.Parameters.WHITE_BALANCE_WARM_FLUORESCENT.equals(wb)) { + mSupportedWhiteBalances.add(WhiteBalance.WARM_FLUORESCENT); + } + } + } + } + + private static class FpsComparator implements Comparator<int[]> { + @Override + public int compare(int[] fps1, int[] fps2) { + return (fps1[0] == fps2[0] ? fps1[1] - fps2[1] : fps1[0] - fps2[0]); + } + } + + private static class SizeComparator implements Comparator<Point> { + + @Override + public int compare(Point size1, Point size2) { + return (size1.x == size2.x ? size1.y - size2.y : size1.x - size2.x); + } + } + + private static class AndroidCameraCapabilityStringifier implements Stringifier { + + @Override + public String stringify(FocusMode focus) { + switch (focus) { + case AUTO: + return Camera.Parameters.FOCUS_MODE_AUTO; + case CONTINUOUS_PICTURE: + return Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE; + case CONTINUOUS_VIDEO: + return Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO; + case EXTENDED_DOF: + return Camera.Parameters.FOCUS_MODE_EDOF; + case FIXED: + return Camera.Parameters.FOCUS_MODE_FIXED; + case INFINITY: + return Camera.Parameters.FOCUS_MODE_INFINITY; + case MACRO: + return Camera.Parameters.FOCUS_MODE_MACRO; + } + return null; + } + + @Override + public FocusMode focusModeFromString(String val) { + if (val.equals(Camera.Parameters.FOCUS_MODE_AUTO)) { + return FocusMode.AUTO; + } else if (val.equals(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) { + return FocusMode.CONTINUOUS_PICTURE; + } else if (val.equals(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) { + return FocusMode.CONTINUOUS_VIDEO; + } else if (val.equals(Camera.Parameters.FOCUS_MODE_EDOF)) { + return FocusMode.EXTENDED_DOF; + } else if (val.equals(Camera.Parameters.FOCUS_MODE_FIXED)) { + return FocusMode.FIXED; + } else if (val.equals(Camera.Parameters.FOCUS_MODE_INFINITY)) { + return FocusMode.INFINITY; + } else if (val.equals(Camera.Parameters.FOCUS_MODE_MACRO)) { + return FocusMode.MACRO; + } else { + return null; + } + } + + @Override + public String stringify(FlashMode flash) { + switch (flash) { + case AUTO: + return Camera.Parameters.FLASH_MODE_AUTO; + case OFF: + return Camera.Parameters.FLASH_MODE_OFF; + case ON: + return Camera.Parameters.FLASH_MODE_ON; + case TORCH: + return Camera.Parameters.FLASH_MODE_TORCH; + case RED_EYE: + return Camera.Parameters.FLASH_MODE_RED_EYE; + } + return null; + } + + @Override + public FlashMode flashModeFromString(String val) { + if (val.equals(Camera.Parameters.FLASH_MODE_AUTO)) { + return FlashMode.AUTO; + } else if (val.equals(Camera.Parameters.FLASH_MODE_OFF)) { + return FlashMode.OFF; + } else if (val.equals(Camera.Parameters.FLASH_MODE_ON)) { + return FlashMode.ON; + } else if (val.equals(Camera.Parameters.FLASH_MODE_TORCH)) { + return FlashMode.TORCH; + } else if (val.equals(Camera.Parameters.FLASH_MODE_RED_EYE)) { + return FlashMode.RED_EYE; + } else { + return null; + } + } + + @Override + public String stringify(SceneMode scene) { + switch (scene) { + case AUTO: + return Camera.Parameters.SCENE_MODE_AUTO; + case ACTION: + return Camera.Parameters.SCENE_MODE_ACTION; + case BARCODE: + return Camera.Parameters.SCENE_MODE_BARCODE; + case BEACH: + return Camera.Parameters.SCENE_MODE_BEACH; + case CANDLELIGHT: + return Camera.Parameters.SCENE_MODE_CANDLELIGHT; + case FIREWORKS: + return Camera.Parameters.SCENE_MODE_FIREWORKS; + case HDR: + return Camera.Parameters.SCENE_MODE_HDR; + case LANDSCAPE: + return Camera.Parameters.SCENE_MODE_LANDSCAPE; + case NIGHT: + return Camera.Parameters.SCENE_MODE_NIGHT; + case NIGHT_PORTRAIT: + return Camera.Parameters.SCENE_MODE_NIGHT_PORTRAIT; + case PARTY: + return Camera.Parameters.SCENE_MODE_PARTY; + case PORTRAIT: + return Camera.Parameters.SCENE_MODE_PORTRAIT; + case SNOW: + return Camera.Parameters.SCENE_MODE_SNOW; + case SPORTS: + return Camera.Parameters.SCENE_MODE_SPORTS; + case STEADYPHOTO: + return Camera.Parameters.SCENE_MODE_STEADYPHOTO; + case SUNSET: + return Camera.Parameters.SCENE_MODE_SUNSET; + case THEATRE: + return Camera.Parameters.SCENE_MODE_THEATRE; + } + return null; + } + + @Override + public SceneMode sceneModeFromString(String val) { + if (val.equals(Camera.Parameters.SCENE_MODE_AUTO)) { + return SceneMode.AUTO; + } else if (val.equals(Camera.Parameters.SCENE_MODE_ACTION)) { + return SceneMode.ACTION; + } else if (val.equals(Camera.Parameters.SCENE_MODE_BARCODE)) { + return SceneMode.BARCODE; + } else if (val.equals(Camera.Parameters.SCENE_MODE_BEACH)) { + return SceneMode.BEACH; + } else if (val.equals(Camera.Parameters.SCENE_MODE_CANDLELIGHT)) { + return SceneMode.CANDLELIGHT; + } else if (val.equals(Camera.Parameters.SCENE_MODE_FIREWORKS)) { + return SceneMode.FIREWORKS; + } else if (val.equals(Camera.Parameters.SCENE_MODE_HDR)) { + return SceneMode.HDR; + } else if (val.equals(Camera.Parameters.SCENE_MODE_LANDSCAPE)) { + return SceneMode.LANDSCAPE; + } else if (val.equals(Camera.Parameters.SCENE_MODE_NIGHT)) { + return SceneMode.NIGHT; + } else if (val.equals(Camera.Parameters.SCENE_MODE_NIGHT_PORTRAIT)) { + return SceneMode.NIGHT_PORTRAIT; + } else if (val.equals(Camera.Parameters.SCENE_MODE_PARTY)) { + return SceneMode.PARTY; + } else if (val.equals(Camera.Parameters.SCENE_MODE_PORTRAIT)) { + return SceneMode.PORTRAIT; + } else if (val.equals(Camera.Parameters.SCENE_MODE_SNOW)) { + return SceneMode.SNOW; + } else if (val.equals(Camera.Parameters.SCENE_MODE_SPORTS)) { + return SceneMode.SPORTS; + } else if (val.equals(Camera.Parameters.SCENE_MODE_STEADYPHOTO)) { + return SceneMode.STEADYPHOTO; + } else if (val.equals(Camera.Parameters.SCENE_MODE_SUNSET)) { + return SceneMode.SUNSET; + } else if (val.equals(Camera.Parameters.SCENE_MODE_THEATRE)) { + return SceneMode.THEATRE; + } else { + return null; + } + } + + @Override + public String stringify(WhiteBalance wb) { + switch (wb) { + case AUTO: + return Camera.Parameters.WHITE_BALANCE_AUTO; + case CLOUDY_DAYLIGHT: + return Camera.Parameters.WHITE_BALANCE_CLOUDY_DAYLIGHT; + case DAYLIGHT: + return Camera.Parameters.WHITE_BALANCE_DAYLIGHT; + case FLUORESCENT: + return Camera.Parameters.WHITE_BALANCE_FLUORESCENT; + case INCANDESCENT: + return Camera.Parameters.WHITE_BALANCE_INCANDESCENT; + case SHADE: + return Camera.Parameters.WHITE_BALANCE_SHADE; + case TWILIGHT: + return Camera.Parameters.WHITE_BALANCE_TWILIGHT; + case WARM_FLUORESCENT: + return Camera.Parameters.WHITE_BALANCE_WARM_FLUORESCENT; + } + return null; + } + + @Override + public WhiteBalance whiteBalanceFromString(String val) { + if (val.equals(Camera.Parameters.WHITE_BALANCE_AUTO)) { + return WhiteBalance.AUTO; + } else if (val.equals(Camera.Parameters.WHITE_BALANCE_CLOUDY_DAYLIGHT)) { + return WhiteBalance.CLOUDY_DAYLIGHT; + } else if (val.equals(Camera.Parameters.WHITE_BALANCE_DAYLIGHT)) { + return WhiteBalance.DAYLIGHT; + } else if (val.equals(Camera.Parameters.WHITE_BALANCE_FLUORESCENT)) { + return WhiteBalance.FLUORESCENT; + } else if (val.equals(Camera.Parameters.WHITE_BALANCE_INCANDESCENT)) { + return WhiteBalance.INCANDESCENT; + } else if (val.equals(Camera.Parameters.WHITE_BALANCE_SHADE)) { + return WhiteBalance.SHADE; + } else if (val.equals(Camera.Parameters.WHITE_BALANCE_TWILIGHT)) { + return WhiteBalance.TWILIGHT; + } else if (val.equals(Camera.Parameters.WHITE_BALANCE_WARM_FLUORESCENT)) { + return WhiteBalance.WARM_FLUORESCENT; + } else { + return null; + } + } + } +} diff --git a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraManagerImpl.java b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraManagerImpl.java index a46d37a..9fa7436 100644 --- a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraManagerImpl.java +++ b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraManagerImpl.java @@ -362,7 +362,9 @@ class AndroidCameraManagerImpl implements CameraManager { mCameraState.setState(CAMERA_IDLE); if (openCallback != null) { openCallback.onCameraOpened( - new AndroidCameraProxyImpl(cameraId, mCamera)); + new AndroidCameraProxyImpl(cameraId, mCamera, + new AndroidCameraCapabilities(mParamsToSet)) + ); } } else { if (openCallback != null) { @@ -399,7 +401,8 @@ class AndroidCameraManagerImpl implements CameraManager { mCameraState.setState(CAMERA_IDLE); if (cbForward != null) { - cbForward.onCameraOpened(new AndroidCameraProxyImpl(cameraId, mCamera)); + cbForward.onCameraOpened(new AndroidCameraProxyImpl(cameraId, mCamera, + new AndroidCameraCapabilities(mParamsToSet))); } break; } @@ -748,10 +751,13 @@ class AndroidCameraManagerImpl implements CameraManager { private final int mCameraId; /* TODO: remove this Camera instance. */ private final Camera mCamera; + private final AndroidCameraCapabilities mCapabilities; - private AndroidCameraProxyImpl(int cameraId, Camera camera) { + private AndroidCameraProxyImpl(int cameraId, Camera camera, + AndroidCameraCapabilities capabilities) { mCamera = camera; mCameraId = cameraId; + mCapabilities = capabilities; } @Override @@ -765,6 +771,11 @@ class AndroidCameraManagerImpl implements CameraManager { } @Override + public CameraCapabilities getCapabilities() { + return new AndroidCameraCapabilities(mCapabilities); + } + + @Override public void reconnect(final Handler handler, final CameraOpenCallback cb) { mDispatchThread.runJob(new Runnable() { @Override @@ -1122,7 +1133,6 @@ class AndroidCameraManagerImpl implements CameraManager { } }); } - } private static class WaitDoneBundle { diff --git a/camera2/portability/src/com/android/ex/camera2/portability/CameraCapabilities.java b/camera2/portability/src/com/android/ex/camera2/portability/CameraCapabilities.java new file mode 100644 index 0000000..bcc97e5 --- /dev/null +++ b/camera2/portability/src/com/android/ex/camera2/portability/CameraCapabilities.java @@ -0,0 +1,537 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ex.camera2.portability; + +import android.graphics.Point; + +import com.android.ex.camera2.portability.debug.Log; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; + +public class CameraCapabilities { + + private static Log.Tag TAG = new Log.Tag("CameraCapabilities"); + + protected final ArrayList<int[]> mSupportedPreviewFpsRange = new ArrayList<int[]>(); + protected final ArrayList<Point> mSupportedPreviewSizes = new ArrayList<Point>(); + protected final TreeSet<Integer> mSupportedPreviewFormats = new TreeSet<Integer>(); + protected final ArrayList<Point> mSupportedVideoSizes = new ArrayList<Point>(); + protected final ArrayList<Point> mSupportedPictureSizes = new ArrayList<Point>(); + protected final TreeSet<Integer> mSupportedPictureFormats = new TreeSet<Integer>(); + protected final EnumSet<SceneMode> mSupportedSceneModes = EnumSet.noneOf(SceneMode.class); + protected final EnumSet<FlashMode> mSupportedFlashModes = EnumSet.noneOf(FlashMode.class); + protected final EnumSet<FocusMode> mSupportedFocusModes = EnumSet.noneOf(FocusMode.class); + protected final EnumSet<WhiteBalance> mSupportedWhiteBalances = + EnumSet.noneOf(WhiteBalance.class); + protected final EnumSet<Feature> mSupportedFeatures = EnumSet.noneOf(Feature.class); + protected int mMinExposureCompensation; + protected int mMaxExposureCompensation; + protected float mExposureCompensationStep; + protected int mMaxNumOfFacesSupported; + protected int mMaxNumOfFocusAreas; + protected int mMaxNumOfMeteringArea; + private final Stringifier mStringifier; + + // Focus modes. + public enum FocusMode { + /** + * Continuous auto focus mode intended for taking pictures. + * @see {@link android.hardware.Camera.Parameters#FOCUS_MODE_AUTO}. + */ + AUTO, + /** + * Continuous auto focus mode intended for taking pictures. + * @see {@link android.hardware.Camera.Parameters#FOCUS_MODE_CONTINUOUS_PICTURE}. + */ + CONTINUOUS_PICTURE, + /** + * Continuous auto focus mode intended for video recording. + * @see {@link android.hardware.Camera.Parameters#FOCUS_MODE_CONTINUOUS_VIDEO}. + */ + CONTINUOUS_VIDEO, + /** + * Extended depth of field (EDOF). + * @see {@link android.hardware.Camera.Parameters#FOCUS_MODE_EDOF}. + */ + EXTENDED_DOF, + /** + * Focus is fixed. + * @see {@link android.hardware.Camera.Parameters#FOCUS_MODE_FIXED}. + */ + FIXED, + /** + * Focus is set at infinity. + * @see {@link android.hardware.Camera.Parameters#FOCUS_MODE_INFINITY}. + */ + INFINITY, + /** + * Macro (close-up) focus mode. + * @see {@link android.hardware.Camera.Parameters#FOCUS_MODE_MACRO}. + */ + MACRO, + } + + // Flash modes. + public enum FlashMode { + /** + * Flash will be fired automatically when required. + * @see {@link android.hardware.Camera.Parameters#FLASH_MODE_OFF}. + */ + AUTO, + /** + * Flash will not be fired. + * @see {@link android.hardware.Camera.Parameters#FLASH_MODE_OFF}. + */ + OFF, + /** + * Flash will always be fired during snapshot. + * @see {@link android.hardware.Camera.Parameters#FLASH_MODE_ON}. + */ + ON, + /** + * Constant emission of light during preview, auto-focus and snapshot. + * @see {@link android.hardware.Camera.Parameters#FLASH_MODE_TORCH}. + */ + TORCH, + /** + * Flash will be fired in red-eye reduction mode. + * @see {@link android.hardware.Camera.Parameters#FLASH_MODE_RED_EYE}. + */ + RED_EYE, + } + + public enum SceneMode { + /** + * Scene mode is off. + * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_AUTO}. + */ + AUTO, + /** + * Take photos of fast moving objects. + * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_ACTION}. + */ + ACTION, + /** + * Applications are looking for a barcode. + * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_BARCODE}. + */ + BARCODE, + /** + * Take pictures on the beach. + * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_BEACH}. + */ + BEACH, + /** + * Capture the naturally warm color of scenes lit by candles. + * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_CANDLELIGHT}. + */ + CANDLELIGHT, + /** + * For shooting firework displays. + * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_FIREWORKS}. + */ + FIREWORKS, + /** + * Capture a scene using high dynamic range imaging techniques. + * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_HDR}. + */ + HDR, + /** + * Take pictures on distant objects. + * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_LANDSCAPE}. + */ + LANDSCAPE, + /** + * Take photos at night. + * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_NIGHT}. + */ + NIGHT, + /** + * Take people pictures at night. + * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_NIGHT_PORTRAIT}. + */ + NIGHT_PORTRAIT, + /** + * Take indoor low-light shot. + * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_PARTY}. + */ + PARTY, + /** + * Take people pictures. + * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_PORTRAIT}. + */ + PORTRAIT, + /** + * Take pictures on the snow. + * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_SNOW}. + */ + SNOW, + /** + * Take photos of fast moving objects. + * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_SPORTS}. + */ + SPORTS, + /** + * Avoid blurry pictures (for example, due to hand shake). + * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_STEADYPHOTO}. + */ + STEADYPHOTO, + /** + * Take sunset photos. + * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_SUNSET}. + */ + SUNSET, + /** + * Take photos in a theater. + * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_THEATRE}. + */ + THEATRE, + } + + // White balances. + public enum WhiteBalance { + /** + * @see {@link android.hardware.Camera.Parameters#WHITE_BALANCE_AUTO}. + */ + AUTO, + /** + * @see {@link android.hardware.Camera.Parameters#WHITE_BALANCE_CLOUDY_DAYLIGHT}. + */ + CLOUDY_DAYLIGHT, + /** + * @see {@link android.hardware.Camera.Parameters#WHITE_BALANCE_DAYLIGHT}. + */ + DAYLIGHT, + /** + * @see {@link android.hardware.Camera.Parameters#WHITE_BALANCE_FLUORESCENT}. + */ + FLUORESCENT, + /** + * @see {@link android.hardware.Camera.Parameters#WHITE_BALANCE_INCANDESCENT}. + */ + INCANDESCENT, + /** + * @see {@link android.hardware.Camera.Parameters#WHITE_BALANCE_SHADE}. + */ + SHADE, + /** + * @see {@link android.hardware.Camera.Parameters#WHITE_BALANCE_TWILIGHT}. + */ + TWILIGHT, + /** + * @see {@link android.hardware.Camera.Parameters#WHITE_BALANCE_WARM_FLUORESCENT}. + */ + WARM_FLUORESCENT, + } + + public enum Feature { + /** + * Support zoom-related methods. + */ + ZOOM, + /** + * Support for photo capturing during video recording. + */ + VIDEO_SNAPSHOT, + /** + * Support for focus area settings. + */ + FOCUS_AREA, + /** + * Support for metering area settings. + */ + METERING_AREA, + /** + * Support for automatic exposure lock. + */ + AUTO_EXPOSURE_LOCK, + /** + * Support for automatic white balance lock. + */ + AUTO_WHITE_BALANCE_LOCK, + } + + /** + * A interface stringifier to convert abstract representations to API + * related string representation. + */ + public interface Stringifier { + /** + * Converts the focus mode to API-related string representation. + * + * @param focus The focus mode to convert. + * @return The string used by the camera framework API to represent the + * focus mode. + */ + String stringify(FocusMode focus); + + /** + * Converts the API-related string representation of the focus mode to the + * abstract representation. + * + * @param val The string representation. + * @return The focus mode represented by the input string. + */ + FocusMode focusModeFromString(String val); + + /** + * Converts the flash mode to API-related string representation. + * + * @param flash The focus mode to convert. + * @return The string used by the camera framework API to represent the + * flash mode. + */ + String stringify(FlashMode flash); + + /** + * Converts the API-related string representation of the flash mode to the + * abstract representation. + * + * @param val The string representation. + * @return The flash mode represented by the input string. + */ + FlashMode flashModeFromString(String val); + + /** + * Converts the scene mode to API-related string representation. + * + * @param scene The focus mode to convert. + * @return The string used by the camera framework API to represent the + * scene mode. + */ + String stringify(SceneMode scene); + + /** + * Converts the API-related string representation of the scene mode to the + * abstract representation. + * + * @param val The string representation. + * @return The scene mode represented by the input string. + */ + SceneMode sceneModeFromString(String val); + + /** + * Converts the white balance to API-related string representation. + * + * @param wb The focus mode to convert. + * @return The string used by the camera framework API to represent the + * white balance. + */ + String stringify(WhiteBalance wb); + + /** + * Converts the API-related string representation of the white balance to + * the abstract representation. + * + * @param val The string representation. + * @return The white balance represented by the input string. + */ + WhiteBalance whiteBalanceFromString(String val); + } + + /** + * constructor. + * @param mStringifier The stringifier used by this instance. + */ + CameraCapabilities(Stringifier mStringifier) { + this.mStringifier = mStringifier; + } + + /** + * Copy constructor. + * @param src The source instance. + */ + public CameraCapabilities(CameraCapabilities src) { + mSupportedPreviewFpsRange.addAll(src.mSupportedPreviewFpsRange); + mSupportedPreviewSizes.addAll(src.mSupportedPreviewSizes); + mSupportedPreviewFormats.addAll(src.mSupportedPreviewFormats); + mSupportedVideoSizes.addAll(src.mSupportedVideoSizes); + mSupportedPictureSizes.addAll(src.mSupportedPictureSizes); + mSupportedPictureFormats.addAll(src.mSupportedPictureFormats); + mSupportedSceneModes.addAll(src.mSupportedSceneModes); + mSupportedFlashModes.addAll(src.mSupportedFlashModes); + mSupportedFocusModes.addAll(src.mSupportedFocusModes); + mSupportedWhiteBalances.addAll(src.mSupportedWhiteBalances); + mSupportedFeatures.addAll(src.mSupportedFeatures); + mMaxExposureCompensation = src.mMaxExposureCompensation; + mMinExposureCompensation = src.mMinExposureCompensation; + mExposureCompensationStep = src.mExposureCompensationStep; + mMaxNumOfFacesSupported = src.mMaxNumOfFacesSupported; + mMaxNumOfFocusAreas = src.mMaxNumOfFocusAreas; + mStringifier = src.mStringifier; + } + + /** + * @return the supported picture formats. See {@link android.graphics.ImageFormat}. + */ + public Set<Integer> getSupportedPictureFormats() { + return new TreeSet<Integer>(mSupportedPictureFormats); + } + + /** + * Gets the supported preview formats. + * @return The supported preview {@link android.graphics.ImageFormat}s. + */ + public Set<Integer> getSupportedPreviewFormats() { + return new TreeSet<Integer>(mSupportedPreviewFormats); + } + + /** + * Gets the supported picture sizes. + */ + public List<Point> getSupportedPictureSizes() { + return new ArrayList<Point>(mSupportedPictureSizes); + } + + + /** + * @return The supported preview fps (frame-per-second) ranges. The returned + * list is sorted by maximum fps then minimum fps in a descending order. + * The values are multiplied by 1000. + */ + public final List<int[]> getSupportedPreviewFpsRange() { + return new ArrayList<int[]>(mSupportedPreviewFpsRange); + } + + /** + * @return The supported preview sizes. The width and height are stored in + * Point.x and Point.y respectively and the list is sorted by width then + * height in a descending order. + */ + public final List<Point> getSupportedPreviewSizes() { + return new ArrayList<Point>(mSupportedPreviewSizes); + } + + /** + * @return The supported video frame sizes that can be used by MediaRecorder. + * The width and height are stored in Point.x and Point.y respectively and + * the list is sorted by width then height in a descending order. + */ + public final List<Point> getSupportedVideoSizes() { + return new ArrayList<Point>(mSupportedVideoSizes); + } + + /** + * @return The supported scene modes. + */ + public final Set<SceneMode> getSupportedSceneModes() { + return new HashSet<SceneMode>(mSupportedSceneModes); + } + + /** + * @return Whether the scene mode is supported. + */ + public final boolean supports(SceneMode scene) { + return (scene != null && mSupportedSceneModes.contains(scene)); + } + + /** + * @return The supported flash modes. + */ + public final Set<FlashMode> getSupportedFlashModes() { + return new HashSet<FlashMode>(mSupportedFlashModes); + } + + /** + * @return Whether the flash mode is supported. + */ + public final boolean supports(FlashMode flash) { + return (flash != null && mSupportedFlashModes.contains(flash)); + } + + /** + * @return The supported focus modes. + */ + public final Set<FocusMode> getSupportedFocusModes() { + return new HashSet<FocusMode>(mSupportedFocusModes); + } + + /** + * @return Whether the focus mode is supported. + */ + public final boolean supports(FocusMode focus) { + return (focus != null && mSupportedFocusModes.contains(focus)); + } + + /** + * @return The supported white balanceas. + */ + public final Set<WhiteBalance> getSupportedWhiteBalance() { + return new HashSet<WhiteBalance>(mSupportedWhiteBalances); + } + + /** + * @return Whether the white balance is supported. + */ + public boolean supports(WhiteBalance wb) { + return (wb != null && mSupportedWhiteBalances.contains(wb)); + } + + public final Set<Feature> getSupportedFeature() { + return new HashSet<Feature>(mSupportedFeatures); + } + + public boolean supports(Feature ft) { + return (ft != null && mSupportedFeatures.contains(ft)); + } + + /** + * @return The min exposure compensation index. The EV is the compensation + * index multiplied by the step value. If unsupported, both this method and + * {@link #getMaxExposureCompensation()} return 0. + */ + public final int getMinExposureCompensation() { + return mMinExposureCompensation; + } + + /** + * @return The max exposure compensation index. The EV is the compensation + * index multiplied by the step value. If unsupported, both this method and + * {@link #getMinExposureCompensation()} return 0. + */ + public final int getMaxExposureCompensation() { + return mMaxExposureCompensation; + } + + /** + * @return The exposure compensation step. The EV is the compensation index + * multiplied by the step value. + */ + public final float getExposureCompensationStep() { + return mExposureCompensationStep; + } + + /** + * @return The max number of faces supported by the face detection. 0 if + * unsupported. + */ + public final int getMaxNumOfFacesSupported() { + return mMaxNumOfFacesSupported; + } + + /** + * @return The stringifier used by this instance. + */ + public Stringifier getStringifier() { + return mStringifier; + } +} diff --git a/camera2/portability/src/com/android/ex/camera2/portability/CameraCapabilitiesFactory.java b/camera2/portability/src/com/android/ex/camera2/portability/CameraCapabilitiesFactory.java new file mode 100644 index 0000000..80765d3 --- /dev/null +++ b/camera2/portability/src/com/android/ex/camera2/portability/CameraCapabilitiesFactory.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ex.camera2.portability; + +import android.hardware.Camera; + +import com.android.ex.camera2.portability.debug.Log; + +public class CameraCapabilitiesFactory { + + private static Log.Tag TAG = new Log.Tag("CapabilitiesFactory"); + + public static CameraCapabilities createFrom(Camera.Parameters p) { + if (p == null) { + Log.w(TAG, "Null parameter passed in."); + return null; + } + return new AndroidCameraCapabilities(p); + } +} diff --git a/camera2/portability/src/com/android/ex/camera2/portability/CameraManager.java b/camera2/portability/src/com/android/ex/camera2/portability/CameraManager.java index a7bddcb..b5707b6 100644 --- a/camera2/portability/src/com/android/ex/camera2/portability/CameraManager.java +++ b/camera2/portability/src/com/android/ex/camera2/portability/CameraManager.java @@ -20,7 +20,6 @@ import android.annotation.TargetApi; import android.graphics.SurfaceTexture; import android.hardware.Camera; import android.hardware.Camera.OnZoomChangeListener; -import android.hardware.Camera.Parameters; import android.os.Build; import android.os.Handler; import android.view.SurfaceHolder; @@ -197,13 +196,17 @@ public interface CameraManager { public android.hardware.Camera getCamera(); /** - * Returns the camera ID associated to by this + * @return The camera ID associated to by this * {@link CameraManager.CameraProxy}. - * @return */ public int getCameraId(); /** + * @return The camera capabilities. + */ + public CameraCapabilities getCapabilities(); + + /** * Reconnects to the camera device. On success, the camera device will * be returned through {@link CameraManager * .CameraOpenCallback#onCameraOpened(com.android.camera.cameradevice.CameraManager @@ -392,7 +395,7 @@ public interface CameraManager { * * @param params The camera parameters to use. */ - public void setParameters(Parameters params); + public void setParameters(Camera.Parameters params); /** * Gets the current camera parameters synchronously. This method is @@ -400,7 +403,7 @@ public interface CameraManager { * the parameters. If the parameters are already cached, it returns * immediately. */ - public Parameters getParameters(); + public Camera.Parameters getParameters(); /** * Forces {@code CameraProxy} to update the cached version of the camera |