Проблема с Nexus 6P: настройте сеанс предварительного просмотра 60 кадров в секунду, используя камеру 2 API
Я пытаюсь реализовать сессию захвата высокой скорости, нажав на кнопку. Вот мой ответный звонок:
private CameraDevice.StateCallback mCameraDeviceStateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(CameraDevice cameraDevice) {
mCameraDevice = cameraDevice;
startPreview();
}
@Override
public void onDisconnected(CameraDevice cameraDevice) {
mCameraOpenCloseLock.release();
cameraDevice.close();
mCameraDevice = null;
}
@Override
public void onError(CameraDevice cameraDevice, int error) {
mCameraOpenCloseLock.release();
cameraDevice.close();
mCameraDevice = null;
}
};
метод открытой камеры:
private void openCamera() throws CameraAccessException {
CameraManager manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
try {
mCameraCharacteristics = manager.getCameraCharacteristics(String.valueOf(currentCamID));
} catch (CameraAccessException e) {
e.printStackTrace();
}
manager.openCamera(String.valueOf(currentCamID), mCameraDeviceStateCallback, mHandler);
}
вызывается при запуске предварительного просмотра и события onClick
private void createCaptureSession(List<Surface> surfaces) throws CameraAccessException {
if(mPreviewSession!=null){
mPreviewSession.close();
mPreviewSession = null;
}
if (!isHighSpeed) {
Log.d(LOG_TAG, "createCaptureSession isHighSpeed" +isHighSpeed );
mCameraDevice.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession cameraCaptureSession) {
Log.i(LOG_TAG, "CameraCaptureSession onConfigured :" + cameraCaptureSession.hashCode());
mPreviewSession = cameraCaptureSession;
updatePreview();
}
@Override
public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) {
}
}, mHandler);
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Log.d(LOG_TAG, "createCaptureSession isHighSpeed" +isHighSpeed );
mCameraDevice.createConstrainedHighSpeedCaptureSession(surfaces, new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession cameraCaptureSession) {
Log.i(LOG_TAG, "CameraCaptureSession onConfigured :" + cameraCaptureSession.hashCode());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
mPreviewSession = cameraCaptureSession;
}
updatePreview();
}
@Override
public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) {
Log.e(LOG_TAG, "failed");
}
}, mHandler);
}
}
}
предварительный просмотр обновления называется выше
private void updatePreview() {
try {
List<CaptureRequest> captureList = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M && isHighSpeed) {
StreamConfigurationMap map = mCameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
Range<Integer>[] highSpeedVideoFpsRanges = map.getHighSpeedVideoFpsRanges();
mPreviewBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, highSpeedVideoFpsRanges[3]);//hardcode, 3 is the highest size for nexus6p
captureList = ((CameraConstrainedHighSpeedCaptureSession) mPreviewSession).createHighSpeedRequestList(mPreviewBuilder.build());
mPreviewSession.setRepeatingBurst(captureList, new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureStarted(CameraCaptureSession session, CaptureRequest request, long timestamp, long frameNumber) {
super.onCaptureStarted(session, request, timestamp, frameNumber);
}
}, mHandler);
} else {
mPreviewSession.setRepeatingRequest(mPreviewBuilder.build(), null, mHandler);
}
} catch (Exception e) {
e.printStackTrace();
}
}
В первый раз все прошло правильно, но, когда я снова пытаюсь запустить приложение, возникает ошибка при открытом устройстве камеры, код ошибки 1 в обратном вызове. Без высоких скоростей все хорошо. Чтобы избежать этой проблемы устройство должно быть перезагружено, что меня озадачило
releasingCamera:
@Override
public void onCamPause() {
// super.onCamPause();
stopPreview();
closeCamera();
stopBackgroundThread();
}
private void closePreviewSession() {
if (mPreviewSession != null) {
mPreviewSession.close();
mPreviewSession = null;
}
}
private void closeCamera() {
try {
mCameraOpenCloseLock.acquire();
if (null != mCamera) {
mCamera.close();
mCamera = null;
}
} catch (InterruptedException e) {
throw new RuntimeException("Interrupted while trying to lock camera closing.");
} finally {
mCameraOpenCloseLock.release();
}
}
private void stopBackgroundThread() {
if (mCameraThread != null) {
mCameraThread.quitSafely();
try {
mCameraThread.join();
mCameraThread = null;
mCameraHandler = null;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}`
Вот фоновый поток для камеры:
private void initCameraThread() {
Log.e(TAG, "init camera thread begin.");
mCameraThread = new HandlerThread("Camera Handler Thread");
mCameraThread.start();
mHandler = new Handler(mCameraThread.getLooper());
Log.e(TAG, "nit camera thread done");
}