/*
* 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;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* The subclass of {@link CameraCapabilities} for Android Camera 1 API.
*/
class AndroidCameraCapabilities extends CameraCapabilities {
private static Log.Tag TAG = new Log.Tag("AndCamCapabs");
/** Conversion from ratios to percentages. */
public static final float ZOOM_MULTIPLIER = 100f;
private FpsComparator mFpsComparator = new FpsComparator();
private SizeComparator mSizeComparator = new SizeComparator();
AndroidCameraCapabilities(Camera.Parameters p) {
super(new Stringifier());
mMaxExposureCompensation = p.getMaxExposureCompensation();
mMinExposureCompensation = p.getMinExposureCompensation();
mExposureCompensationStep = p.getExposureCompensationStep();
mMaxNumOfFacesSupported = p.getMaxNumDetectedFaces();
mMaxNumOfMeteringArea = p.getMaxNumMeteringAreas();
mPreferredPreviewSizeForVideo = new Size(p.getPreferredPreviewSizeForVideo());
mSupportedPreviewFormats.addAll(p.getSupportedPreviewFormats());
mSupportedPhotoFormats.addAll(p.getSupportedPictureFormats());
mHorizontalViewAngle = p.getHorizontalViewAngle();
mVerticalViewAngle = p.getVerticalViewAngle();
buildPreviewFpsRange(p);
buildPreviewSizes(p);
buildVideoSizes(p);
buildPictureSizes(p);
buildSceneModes(p);
buildFlashModes(p);
buildFocusModes(p);
buildWhiteBalances(p);
if (p.isZoomSupported()) {
mMaxZoomRatio = p.getZoomRatios().get(p.getMaxZoom()) / ZOOM_MULTIPLIER;
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 Size(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 Size(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) {
mSupportedPhotoSizes.add(new Size(s.width, s.height));
}
}
Collections.sort(mSupportedPhotoSizes, 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) {
// Camera 1 will return NULL if no flash mode is supported.
mSupportedFlashModes.add(FlashMode.NO_FLASH);
} else {
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);
} else if (Camera.Parameters.FLASH_MODE_TORCH.equals(flash)) {
mSupportedFlashModes.add(FlashMode.TORCH);
}
}
}
}
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<Size> {
@Override
public int compare(Size size1, Size size2) {
return (size1.width() == size2.width() ? size1.height() - size2.height() :
size1.width() - size2.width());
}
}
}