セマフォとロックとPauseからの復帰
- セマフォは獲得してから解放するまでのコードを一つのスレッドしか通ってくれるなよ、的なもの
- 1つ、というのはコンストラクタの引数1から
- 同時に実行していい数が指定できるロック的な
- と現状理解している
- 1つ、というのはコンストラクタの引数1から
- サンプル見てるとこのセマフォでCamera2 APIの利用のタイミングの同期を取っているっぽい
- 獲得 ~ 解放までの流れ 1
- 獲得 ~ 解放までの流れ 2
- CameraCaptureSession, CameraDevice, 他のSurface をcloseする前に獲得
- 上記close後 or closeに失敗した後に解放
- ちなみに昨日の自分のコードはそもそも
onPause
でCameraDevice
をcloseしていなかったのでした…
獲得 ~ 解放までの流れ 1
/** * A {@link Semaphore} to prevent the app from exiting before closing the camera. */ private Semaphore mCameraOpenCloseLock = new Semaphore(1);
/** * Opens the camera specified by {@link Camera2BasicFragment#mCameraId}. */ private void openCamera(int width, int height) { if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { requestCameraPermission(); return; } setUpCameraOutputs(width, height); configureTransform(width, height); Activity activity = getActivity(); CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE); try { if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) { throw new RuntimeException("Time out waiting to lock camera opening."); } manager.openCamera(mCameraId, mStateCallback, mBackgroundHandler); } catch (CameraAccessException e) { e.printStackTrace(); } catch (InterruptedException e) { throw new RuntimeException("Interrupted while trying to lock camera opening.", e); } }
private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() { @Override public void onOpened(@NonNull CameraDevice cameraDevice) { // This method is called when the camera is opened. We start camera preview here. mCameraOpenCloseLock.release(); mCameraDevice = cameraDevice; createCameraPreviewSession(); } @Override public void onDisconnected(@NonNull CameraDevice cameraDevice) { mCameraOpenCloseLock.release(); cameraDevice.close(); mCameraDevice = null; } @Override public void onError(@NonNull CameraDevice cameraDevice, int error) { mCameraOpenCloseLock.release(); cameraDevice.close(); mCameraDevice = null; Activity activity = getActivity(); if (null != activity) { activity.finish(); } } };
獲得 ~ 解放までの流れ 2
/** * Closes the current {@link CameraDevice}. */ private void closeCamera() { try { mCameraOpenCloseLock.acquire(); if (null != mCaptureSession) { mCaptureSession.close(); mCaptureSession = null; } if (null != mCameraDevice) { mCameraDevice.close(); mCameraDevice = null; } if (null != mImageReader) { mImageReader.close(); mImageReader = null; } } catch (InterruptedException e) { throw new RuntimeException("Interrupted while trying to lock camera closing.", e); } finally { mCameraOpenCloseLock.release(); } }
回転とかでうまく表示されなくなるの、デバイスとかのせいでないことがわかったから回転再チャレンジしてもいいかも
- [既存課題]縦向きの場合と横向きの場合でちょうどいいrotationのMatrixを見つける 関連: http://mslgt.hatenablog.com/entry/2015/05/12/013013#rotatescreen 横向き or 縦向きだけの対応で十分では、となり、横向き固定の場合の行列見つけて安堵中
- [既存課題]縦向きの場合と横向きの場合でそれぞれちょうどよくCameraのPreviewが表示されるようにする
- [新しい課題]作成した画像のファイルへの書き込み、あるいはImageWriter
- [新しい課題]ImageReaderでできること他に
- [新しい課題]TextureViewのカスタムクラス読みに行ってはどうか