6 import android.annotation.TargetApi;
7 import android.content.Context;
8 import android.content.pm.PackageManager;
9 import android.graphics.ImageFormat;
10 import android.hardware.camera2.CameraAccessException;
11 import android.hardware.camera2.CameraCaptureSession;
12 import android.hardware.camera2.CameraCharacteristics;
13 import android.hardware.camera2.CameraDevice;
14 import android.hardware.camera2.CameraManager;
15 import android.hardware.camera2.CaptureRequest;
16 import android.hardware.camera2.params.StreamConfigurationMap;
17 import android.media.Image;
18 import android.media.ImageReader;
19 import android.os.Build;
20 import android.os.Handler;
21 import android.os.HandlerThread;
22 import android.util.Log;
23 import android.util.Size;
24 import android.view.Surface;
26 import junit.framework.Assert;
28 import java.util.ArrayList;
29 import java.util.List;
31 @TargetApi(Build.VERSION_CODES.M)
36 private byte[] yuvBuffer = null;
38 private static final int REQUEST_CAMERA_PERMISSION = 1;
40 private HandlerThread backgroundThread;
41 private Handler backgroundHandler;
42 private ImageReader previewReader;
45 private CaptureRequest.Builder previewRequestBuilder;
46 private CameraCaptureSession captureSession;
47 private CaptureRequest previewRequest;
48 private boolean keepSendNewFrame =
false;
54 private void startInternal(
int id,
int width,
int height) {
55 startBackgroundThread();
58 CameraManager manager = (CameraManager)
MaxstARJNI.getContext().getSystemService(Context.CAMERA_SERVICE);
59 String strCameraId = manager.getCameraIdList()[id];
60 CameraCharacteristics characteristics = manager.getCameraCharacteristics(strCameraId);
62 StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
63 Size[] sizes = map.getOutputSizes(ImageFormat.YUV_420_888);
65 ArrayList<CameraSize> cameraSizes =
new ArrayList<>();
66 for (Size size : sizes) {
67 cameraSizes.add(
new CameraSize(size.getWidth(), size.getHeight()));
70 cameraSize = getOptimalPreviewSize(cameraSizes, width, height);
72 previewReader = ImageReader.newInstance(cameraSize.width, cameraSize.height, ImageFormat.YUV_420_888, 2);
73 previewReader.setOnImageAvailableListener(mOnPreviewFrameListener, null);
75 manager.openCamera(strCameraId, mStateCallback, null);
76 }
catch (CameraAccessException e) {
82 private int testCount = 0;
85 public int start(
final int cameraId,
final int width,
final int height) {
86 if (!checkPermission()) {
87 return ResultCode.CameraPermissionIsNotGranted.getValue();
93 return ResultCode.CameraAlreadyOpened.getValue();
97 startInternal(cameraId, width, height);
107 keepSendNewFrame =
false;
119 stopBackgroundThread();
120 cameraSize.width = 0;
121 cameraSize.height = 0;
122 if (cameraSurfaceTexture != null) {
123 cameraSurfaceTexture.release();
124 cameraSurfaceTexture = null;
132 private final ImageReader.OnImageAvailableListener mOnPreviewFrameListener =
new ImageReader.OnImageAvailableListener() {
134 public void onImageAvailable(
final ImageReader reader) {
137 Image acquiredImage = reader.acquireNextImage();
138 if (acquiredImage == null) {
142 Assert.assertTrue(
"Image format is not ImageFormat.YUV_420_888", acquiredImage.getFormat() == ImageFormat.YUV_420_888);
144 int width = acquiredImage.getWidth();
145 int height = acquiredImage.getHeight();
148 Image.Plane yPlane = acquiredImage.getPlanes()[0];
149 int ySize = yPlane.getBuffer().remaining();
151 Image.Plane uPlane = acquiredImage.getPlanes()[1];
152 Image.Plane vPlane = acquiredImage.getPlanes()[2];
156 int uSize = uPlane.getBuffer().remaining();
157 int vSize = vPlane.getBuffer().remaining();
160 if (ySize / 2 - vSize > 0) {
161 margin = ySize / 2 - vSize;
164 if (yuvBuffer == null || yuvBuffer.length < ySize + uSize + vSize) {
165 yuvBuffer =
new byte[ySize + uSize + vSize + 100];
168 yPlane.getBuffer().get(yuvBuffer, 0, ySize);
170 int uvPixelStride = uPlane.getPixelStride();
171 if (uvPixelStride == 1) {
172 uPlane.getBuffer().get(yuvBuffer, ySize, uSize);
173 vPlane.getBuffer().get(yuvBuffer, ySize + uSize, vSize);
176 vPlane.getBuffer().get(yuvBuffer, ySize, vSize);
177 uPlane.getBuffer().get(yuvBuffer, ySize + vSize + margin, uSize);
187 if (keepSendNewFrame) {
188 CameraController.setNewCameraFrame(yuvBuffer, yuvBuffer.length, width, height, colorFormat.getValue());
191 acquiredImage.close();
200 createCameraPreviewSession();
205 cameraDevice.close();
211 public void onError(
CameraDevice cameraDevice,
int error) {
212 cameraDevice.close();
218 @TargetApi(Build.VERSION_CODES.LOLLIPOP)
219 private void createCameraPreviewSession() {
235 Surface surface = previewReader.getSurface();
236 List<Surface> surfaces =
new ArrayList<Surface>();
237 surfaces.add(surface);
239 previewRequestBuilder = cameraDevice.createCaptureRequest(
CameraDevice.TEMPLATE_PREVIEW);
240 previewRequestBuilder.addTarget(surface);
243 cameraDevice.createCaptureSession(surfaces,
new CameraCaptureSession.StateCallback() {
245 public void onConfigured(CameraCaptureSession cameraCaptureSession) {
246 if (null == cameraDevice) {
249 captureSession = cameraCaptureSession;
250 previewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
253 previewRequest = previewRequestBuilder.build();
256 captureSession.setRepeatingRequest(previewRequest, null, null);
258 keepSendNewFrame =
true;
259 }
catch (CameraAccessException e) {
268 public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) {
274 }
catch (CameraAccessException e) {
280 private void closeCamera() {
281 if (null != captureSession) {
282 captureSession.close();
283 captureSession = null;
286 if (null != previewReader) {
287 previewReader.setOnImageAvailableListener(null, null);
288 previewReader.close();
289 previewReader = null;
292 if (null != cameraDevice) {
293 cameraDevice.close();
297 Log.i(TAG,
"Android closeCamera completed");
302 private void startBackgroundThread() {
303 backgroundThread =
new HandlerThread(
"CameraBackground");
304 backgroundThread.start();
305 backgroundHandler =
new Handler(backgroundThread.getLooper());
308 private void stopBackgroundThread() {
309 backgroundThread.quitSafely();
311 backgroundThread.join();
312 backgroundThread = null;
313 }
catch (InterruptedException e) {
320 return cameraSize.width;
325 return cameraSize.height;
329 boolean setFocusMode(
int focusMode) {
334 boolean setFlashLightMode(
boolean on) {
339 boolean setAutoWhiteBalanceLock(
boolean toggle) {
344 Object[] getParamList() {
345 return new String[0];
349 boolean setParam(String key, String value) {
353 private boolean checkPermission() {
354 Context androidContext =
MaxstARJNI.getContext();
355 PackageManager pm = androidContext.getPackageManager();
356 int permissionIsGranted = pm.checkPermission(
"android.permission.CAMERA", androidContext.getPackageName());
357 return permissionIsGranted == 0;