ボタンをクリックして高速キャプチャセッションを実装しようとしています。これが私の状態のコールバックです:
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 が表示されます。高い fps を実行しなくても、すべて問題ありません。この問題を回避するには、デバイスを再起動する必要があります。
解放カメラ:
@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");
}