/*
CameraUtils.java
Copyright (c) 2015 NTT DOCOMO,INC.
Released under the MIT license
http://opensource.org/licenses/mit-license.php
*/
package org.deviceconnect.android.deviceplugin.webrtc.util;
import android.hardware.Camera;
import android.util.Log;
import org.deviceconnect.android.deviceplugin.webrtc.BuildConfig;
import java.util.ArrayList;
import java.util.List;
/**
* Utility to operate the camera.
*
* @author NTT DOCOMO, INC.
*/
@SuppressWarnings("deprecation")
public final class CameraUtils {
/**
* Tag for debugging.
*/
private static final String TAG = "CAMERA";
private CameraUtils() {
}
/**
* Gets a list of CameraFormat by id.
* <p>
* id follows:
* <ul>
* <li>{@link android.hardware.Camera.CameraInfo#CAMERA_FACING_BACK}</li>
* <li>{@link android.hardware.Camera.CameraInfo#CAMERA_FACING_FRONT}</li>
* </ul>
* </p>
* @param id id
* @retur list of CameraFormat
*/
public static List<CameraFormat> getSupportedFormats(final int id) {
final ArrayList<CameraFormat> formatList = new ArrayList<>();
Camera camera;
try {
camera = Camera.open(id);
} catch (Exception e) {
return formatList;
}
try {
Camera.Parameters parameters = camera.getParameters();
List<int[]> listFpsRange = parameters.getSupportedPreviewFpsRange();
int[] range = { 0, 0 };
if (listFpsRange != null) {
range = listFpsRange.get(listFpsRange.size() - 1);
}
List<Camera.Size> supportedSizes = parameters.getSupportedPreviewSizes();
for (Camera.Size size : supportedSizes) {
formatList.add(new CameraFormat(size.width, size.height, id,
range[Camera.Parameters.PREVIEW_FPS_MIN_INDEX]/1000,
range[Camera.Parameters.PREVIEW_FPS_MAX_INDEX]/1000));
}
} catch (Exception e) {
if (BuildConfig.DEBUG) {
Log.w(TAG, "", e);
}
} finally {
camera.release();
}
return formatList;
}
/**
* Checks whether this device support a front camera.
* @return true if this device support a front camera, false otherwise
*/
public static boolean hasFrontFacingDevice() {
for (int i = 0; i < Camera.getNumberOfCameras(); ++i) {
Camera.CameraInfo info = new Camera.CameraInfo();
try {
Camera.getCameraInfo(i, info);
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
return true;
}
} catch (Exception e) {
// do nothing.
}
}
return false;
}
/**
* Gets the default CameraFormat by id.
* @return default CameraFormat
*/
private static CameraFormat getDefaultFormat(final int id, final int width, final int height) {
CameraFormat selectCameraFormat = null;
int dist = Integer.MAX_VALUE;
List<CameraFormat> formats = getSupportedFormats(id);
if (formats != null) {
for (CameraFormat format : formats) {
int dw = format.getWidth() - width;
int dh = format.getHeight() - height;
int d = dw * dw + dh * dh;
if (selectCameraFormat == null || d < dist) {
selectCameraFormat = format;
dist = d;
}
}
}
return selectCameraFormat;
}
/**
* Gets the default CameraFormat.
* @return default CameraFormat
*/
public static CameraFormat getDefaultFormat() {
return getDefaultFormat(320, 240);
}
/**
* Gets the default CameraFormat.
* @param width width of camera
* @param height height of camera
* @return default CameraFormat
*/
public static CameraFormat getDefaultFormat(int width, int height) {
if (hasFrontFacingDevice()) {
return getDefaultFormat(Camera.CameraInfo.CAMERA_FACING_FRONT, width, height);
} else {
return getDefaultFormat(Camera.CameraInfo.CAMERA_FACING_BACK, width, height);
}
}
/**
* Converts the CameraFormat to String.
* @param format CameraFormat
* @return String
*/
public static String formatToText(final CameraFormat format) {
StringBuilder builder = new StringBuilder();
builder.append("size:[" + format.getWidth() + "x" + format.getHeight() + "]");
builder.append(",");
builder.append("fps:[" + format.getMinFrameRate() + "-" + format.getMaxFrameRate() + "]");
builder.append(",");
if (format.getFacing() == Camera.CameraInfo.CAMERA_FACING_BACK) {
builder.append("facing: back");
} else if (format.getFacing() == Camera.CameraInfo.CAMERA_FACING_FRONT) {
builder.append("facing: front");
}
return builder.toString();
}
/**
* Converts the String to CameraFormat.
* @param text text
* @return CameraFormat
*/
public static CameraFormat textToFormat(final String text) {
if (text == null || text.length() == 0) {
return null;
}
String[] txt = text.split(",");
if (txt.length != 3) {
if (BuildConfig.DEBUG) {
Log.e(TAG, "text format is invalid.");
}
return null;
}
try {
String sizeStr = txt[0].substring("size:[".length(), txt[0].length() - 1);
String fpsStr = txt[1].substring("fps:[".length(), txt[1].length() - 1);
String facingStr = txt[2].substring("facing: ".length());
String[] size = sizeStr.split("x");
int width = Integer.parseInt(size[0]);
int height = Integer.parseInt(size[1]);
String[] fps = fpsStr.split("-");
int minFps = Integer.parseInt(fps[0]);
int maxFps = Integer.parseInt(fps[1]);
int facing = Camera.CameraInfo.CAMERA_FACING_FRONT;
if (facingStr.equals("front")) {
facing = Camera.CameraInfo.CAMERA_FACING_FRONT;
} else if (facingStr.equals("back")) {
facing = Camera.CameraInfo.CAMERA_FACING_BACK;
}
return new CameraFormat(width, height, facing, minFps, maxFps);
} catch (Exception e) {
if (BuildConfig.DEBUG) {
Log.e(TAG, "", e);
}
return null;
}
}
/**
* CameraFormat.
*
* @author NTT DOCOMO, INC.
*/
public static class CameraFormat {
/**
* Width of camera.
*/
private int mWidth;
/**
* Height of camera.
*/
private int mHeight;
/**
* The number of the maximum fps.
*/
private int mMaxFrameRate;
/**
* The number of the minimum fps.
*/
private int mMinFrameRate;
/**
* Facing of camera.
*/
private int mFacing;
/**
* Constructor.
* @param width width
* @param height height
* @param facing facing
* @param minFrameRate minimum fps
* @param maxFrameRate maximum fps
*/
public CameraFormat(final int width, final int height, final int facing,
final int minFrameRate, final int maxFrameRate) {
mWidth = width;
mHeight = height;
mFacing = facing;
mMinFrameRate = minFrameRate;
mMaxFrameRate = maxFrameRate;
}
/**
* Gets the width of camera.
* @return width
*/
public int getWidth() {
return mWidth;
}
/**
* Gets the height of camera.
* @return height
*/
public int getHeight() {
return mHeight;
}
/**
* Gets the number of the maximum fps.
* @return fps
*/
public int getMaxFrameRate() {
return mMaxFrameRate;
}
/**
* Gets the number of the minimum fps.
* @return fps
*/
public int getMinFrameRate() {
return mMinFrameRate;
}
/**
* Gets the facing of camera.
* @return facing
*/
public int getFacing() {
return mFacing;
}
/**
* Sets the width of camera.
* @param width width
*/
public void setWidth(final int width) {
mWidth = width;
}
/**
* Sets the height of camera.
* @param height height
*/
public void setHeight(final int height) {
mHeight = height;
}
/**
* Sets the number of the maximum fps.
* @param maxFrameRate fps
*/
public void setMaxFrameRate(int maxFrameRate) {
mMaxFrameRate = maxFrameRate;
}
/**
* Sets the number of the minimum fps.
* @param minFrameRate fps
*/
public void setMinFrameRate(int minFrameRate) {
mMinFrameRate = minFrameRate;
}
/**
* Sets the facing of camera.
*
* facing follows:
* <ul>
* <li>{@link android.hardware.Camera.CameraInfo#CAMERA_FACING_BACK}</li>
* <li>{@link android.hardware.Camera.CameraInfo#CAMERA_FACING_FRONT}</li>
* </ul>
*
* @param facing facing
*/
public void setFacing(int facing) {
mFacing = facing;
}
@Override
public String toString() {
return formatToText(this);
}
}
}